mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 12:36:35 +03:00
Auto merge of #138151 - matthiaskrgr:rollup-j0p6ed1, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #136667 (Revert vita's c_char back to i8) - #137107 (Override default `Write` methods for cursor-like types) - #137777 (Specialize `OsString::push` and `OsString as From` for UTF-8) - #137832 (Fix crash in BufReader::peek()) - #137904 (Improve the generic MIR in the default `PartialOrd::le` and friends) - #138115 (Suggest typo fix for static lifetime) - #138125 (Simplify `printf` and shell format suggestions) - #138129 (Stabilize const_char_classify, const_sockaddr_setters) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -711,11 +711,9 @@ macro_rules! check_foreign {
|
||||
};
|
||||
|
||||
let pos = sub.position();
|
||||
let sub = String::from(sub.as_str());
|
||||
if explained.contains(&sub) {
|
||||
if !explained.insert(sub.to_string()) {
|
||||
continue;
|
||||
}
|
||||
explained.insert(sub);
|
||||
|
||||
if !found_foreign {
|
||||
found_foreign = true;
|
||||
|
||||
@@ -12,14 +12,16 @@ pub(crate) enum Substitution<'a> {
|
||||
Escape((usize, usize)),
|
||||
}
|
||||
|
||||
impl<'a> Substitution<'a> {
|
||||
pub(crate) fn as_str(&self) -> &str {
|
||||
impl ToString for Substitution<'_> {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Substitution::Format(fmt) => fmt.span,
|
||||
Substitution::Escape(_) => "%%",
|
||||
Substitution::Format(fmt) => fmt.span.into(),
|
||||
Substitution::Escape(_) => "%%".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Substitution<'_> {
|
||||
pub(crate) fn position(&self) -> InnerSpan {
|
||||
match self {
|
||||
Substitution::Format(fmt) => fmt.position,
|
||||
@@ -627,15 +629,17 @@ pub(crate) enum Substitution<'a> {
|
||||
Escape((usize, usize)),
|
||||
}
|
||||
|
||||
impl Substitution<'_> {
|
||||
pub(crate) fn as_str(&self) -> String {
|
||||
impl ToString for Substitution<'_> {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Substitution::Ordinal(n, _) => format!("${n}"),
|
||||
Substitution::Name(n, _) => format!("${n}"),
|
||||
Substitution::Escape(_) => "$$".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Substitution<'_> {
|
||||
pub(crate) fn position(&self) -> InnerSpan {
|
||||
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
|
||||
InnerSpan::new(pos.0, pos.1)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{Session, lint};
|
||||
use rustc_span::edit_distance::find_best_match_for_name;
|
||||
use rustc_span::edit_distance::{edit_distance, find_best_match_for_name};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
@@ -2919,23 +2919,35 @@ pub(crate) fn emit_undeclared_lifetime_error(
|
||||
)
|
||||
.with_span_label(lifetime_ref.ident.span, "undeclared lifetime")
|
||||
};
|
||||
self.suggest_introducing_lifetime(
|
||||
&mut err,
|
||||
Some(lifetime_ref.ident.name.as_str()),
|
||||
|err, _, span, message, suggestion, span_suggs| {
|
||||
err.multipart_suggestion_with_style(
|
||||
message,
|
||||
std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
if span_suggs.is_empty() {
|
||||
SuggestionStyle::ShowCode
|
||||
} else {
|
||||
SuggestionStyle::ShowAlways
|
||||
},
|
||||
);
|
||||
true
|
||||
},
|
||||
);
|
||||
|
||||
// Check if this is a typo of `'static`.
|
||||
if edit_distance(lifetime_ref.ident.name.as_str(), "'static", 2).is_some() {
|
||||
err.span_suggestion_verbose(
|
||||
lifetime_ref.ident.span,
|
||||
"you may have misspelled the `'static` lifetime",
|
||||
"'static",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
self.suggest_introducing_lifetime(
|
||||
&mut err,
|
||||
Some(lifetime_ref.ident.name.as_str()),
|
||||
|err, _, span, message, suggestion, span_suggs| {
|
||||
err.multipart_suggestion_with_style(
|
||||
message,
|
||||
std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
if span_suggs.is_empty() {
|
||||
SuggestionStyle::ShowCode
|
||||
} else {
|
||||
SuggestionStyle::ShowAlways
|
||||
},
|
||||
);
|
||||
true
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ pub const fn from_digit(num: u32, radix: u32) -> Option<char> {
|
||||
/// '1'.is_digit(1);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
|
||||
#[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn is_digit(self, radix: u32) -> bool {
|
||||
self.to_digit(radix).is_some()
|
||||
@@ -886,7 +886,7 @@ pub const fn is_uppercase(self) -> bool {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
|
||||
#[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[inline]
|
||||
pub const fn is_whitespace(self) -> bool {
|
||||
match self {
|
||||
|
||||
+16
-6
@@ -397,6 +397,12 @@ pub enum Ordering {
|
||||
}
|
||||
|
||||
impl Ordering {
|
||||
#[inline]
|
||||
const fn as_raw(self) -> i8 {
|
||||
// FIXME(const-hack): just use `PartialOrd` against `Equal` once that's const
|
||||
crate::intrinsics::discriminant_value(&self)
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is the `Equal` variant.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -413,7 +419,11 @@ impl Ordering {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_eq(self) -> bool {
|
||||
matches!(self, Equal)
|
||||
// All the `is_*` methods are implemented as comparisons against zero
|
||||
// to follow how clang's libcxx implements their equivalents in
|
||||
// <https://github.com/llvm/llvm-project/blob/60486292b79885b7800b082754153202bef5b1f0/libcxx/include/__compare/is_eq.h#L23-L28>
|
||||
|
||||
self.as_raw() == 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is not the `Equal` variant.
|
||||
@@ -432,7 +442,7 @@ pub const fn is_eq(self) -> bool {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_ne(self) -> bool {
|
||||
!matches!(self, Equal)
|
||||
self.as_raw() != 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is the `Less` variant.
|
||||
@@ -451,7 +461,7 @@ pub const fn is_ne(self) -> bool {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_lt(self) -> bool {
|
||||
matches!(self, Less)
|
||||
self.as_raw() < 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is the `Greater` variant.
|
||||
@@ -470,7 +480,7 @@ pub const fn is_lt(self) -> bool {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_gt(self) -> bool {
|
||||
matches!(self, Greater)
|
||||
self.as_raw() > 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is either the `Less` or `Equal` variant.
|
||||
@@ -489,7 +499,7 @@ pub const fn is_gt(self) -> bool {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_le(self) -> bool {
|
||||
!matches!(self, Greater)
|
||||
self.as_raw() <= 0
|
||||
}
|
||||
|
||||
/// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
|
||||
@@ -508,7 +518,7 @@ pub const fn is_le(self) -> bool {
|
||||
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
#[stable(feature = "ordering_helpers", since = "1.53.0")]
|
||||
pub const fn is_ge(self) -> bool {
|
||||
!matches!(self, Less)
|
||||
self.as_raw() >= 0
|
||||
}
|
||||
|
||||
/// Reverses the `Ordering`.
|
||||
|
||||
@@ -39,7 +39,6 @@ mod c_char_definition {
|
||||
// These are the targets on which c_char is unsigned. Usually the
|
||||
// signedness is the same for all target_os values on a given architecture
|
||||
// but there are some exceptions (see isSignedCharDefault() in clang).
|
||||
//
|
||||
// aarch64:
|
||||
// Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
|
||||
// 64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
|
||||
@@ -97,14 +96,19 @@ mod c_char_definition {
|
||||
// are promoted to int as if from type signed char by default, unless the /J compilation
|
||||
// option is used."
|
||||
// https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
|
||||
// Vita:
|
||||
// Chars are signed by default on the Vita, and VITASDK follows that convention.
|
||||
// https://github.com/vitasdk/buildscripts/blob/09c533b771591ecde88864b6acad28ffb688dbd4/patches/gcc/0001-gcc-10.patch#L33-L34
|
||||
//
|
||||
// L4Re:
|
||||
// The kernel builds with -funsigned-char on all targets (but useserspace follows the
|
||||
// The kernel builds with -funsigned-char on all targets (but userspace follows the
|
||||
// architecture defaults). As we only have a target for userspace apps so there are no
|
||||
// special cases for L4Re below.
|
||||
// https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
|
||||
if #[cfg(all(
|
||||
not(windows),
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "vita"),
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
|
||||
@@ -200,7 +200,7 @@ pub const fn ip(&self) -> IpAddr {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_ip(&mut self, new_ip: IpAddr) {
|
||||
// `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
|
||||
match (self, new_ip) {
|
||||
@@ -244,7 +244,7 @@ pub const fn port(&self) -> u16 {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_port(&mut self, new_port: u16) {
|
||||
match *self {
|
||||
SocketAddr::V4(ref mut a) => a.set_port(new_port),
|
||||
@@ -350,7 +350,7 @@ pub const fn ip(&self) -> &Ipv4Addr {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_ip(&mut self, new_ip: Ipv4Addr) {
|
||||
self.ip = new_ip;
|
||||
}
|
||||
@@ -386,7 +386,7 @@ pub const fn port(&self) -> u16 {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_port(&mut self, new_port: u16) {
|
||||
self.port = new_port;
|
||||
}
|
||||
@@ -448,7 +448,7 @@ pub const fn ip(&self) -> &Ipv6Addr {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_ip(&mut self, new_ip: Ipv6Addr) {
|
||||
self.ip = new_ip;
|
||||
}
|
||||
@@ -484,7 +484,7 @@ pub const fn port(&self) -> u16 {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_port(&mut self, new_port: u16) {
|
||||
self.port = new_port;
|
||||
}
|
||||
@@ -532,7 +532,7 @@ pub const fn flowinfo(&self) -> u32 {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_flowinfo(&mut self, new_flowinfo: u32) {
|
||||
self.flowinfo = new_flowinfo;
|
||||
}
|
||||
@@ -575,7 +575,7 @@ pub const fn scope_id(&self) -> u32 {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
|
||||
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn set_scope_id(&mut self, new_scope_id: u32) {
|
||||
self.scope_id = new_scope_id;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,30 @@ pub fn into_string(self) -> Result<String, OsString> {
|
||||
#[inline]
|
||||
#[rustc_confusables("append", "put")]
|
||||
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
|
||||
self.inner.push_slice(&s.as_ref().inner)
|
||||
trait SpecPushTo {
|
||||
fn spec_push_to(&self, buf: &mut OsString);
|
||||
}
|
||||
|
||||
impl<T: AsRef<OsStr>> SpecPushTo for T {
|
||||
#[inline]
|
||||
default fn spec_push_to(&self, buf: &mut OsString) {
|
||||
buf.inner.push_slice(&self.as_ref().inner);
|
||||
}
|
||||
}
|
||||
|
||||
// Use a more efficient implementation when the string is UTF-8.
|
||||
macro spec_str($T:ty) {
|
||||
impl SpecPushTo for $T {
|
||||
#[inline]
|
||||
fn spec_push_to(&self, buf: &mut OsString) {
|
||||
buf.inner.push_str(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
spec_str!(str);
|
||||
spec_str!(String);
|
||||
|
||||
s.spec_push_to(self)
|
||||
}
|
||||
|
||||
/// Creates a new `OsString` with at least the given capacity.
|
||||
@@ -587,7 +610,30 @@ impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
|
||||
/// Copies any value implementing <code>[AsRef]<[OsStr]></code>
|
||||
/// into a newly allocated [`OsString`].
|
||||
fn from(s: &T) -> OsString {
|
||||
s.as_ref().to_os_string()
|
||||
trait SpecToOsString {
|
||||
fn spec_to_os_string(&self) -> OsString;
|
||||
}
|
||||
|
||||
impl<T: AsRef<OsStr>> SpecToOsString for T {
|
||||
#[inline]
|
||||
default fn spec_to_os_string(&self) -> OsString {
|
||||
self.as_ref().to_os_string()
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the known-UTF-8 property for strings.
|
||||
macro spec_str($T:ty) {
|
||||
impl SpecToOsString for $T {
|
||||
#[inline]
|
||||
fn spec_to_os_string(&self) -> OsString {
|
||||
OsString::from(String::from(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
spec_str!(str);
|
||||
spec_str!(String);
|
||||
|
||||
s.spec_to_os_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,16 +118,16 @@ impl<R: Read + ?Sized> BufReader<R> {
|
||||
/// #![feature(bufreader_peek)]
|
||||
/// use std::io::{Read, BufReader};
|
||||
///
|
||||
/// let mut bytes = &b"oh, hello"[..];
|
||||
/// let mut bytes = &b"oh, hello there"[..];
|
||||
/// let mut rdr = BufReader::with_capacity(6, &mut bytes);
|
||||
/// assert_eq!(rdr.peek(2).unwrap(), b"oh");
|
||||
/// let mut buf = [0; 4];
|
||||
/// rdr.read(&mut buf[..]).unwrap();
|
||||
/// assert_eq!(&buf, b"oh, ");
|
||||
/// assert_eq!(rdr.peek(2).unwrap(), b"he");
|
||||
/// assert_eq!(rdr.peek(5).unwrap(), b"hello");
|
||||
/// let mut s = String::new();
|
||||
/// rdr.read_to_string(&mut s).unwrap();
|
||||
/// assert_eq!(&s, "hello");
|
||||
/// assert_eq!(&s, "hello there");
|
||||
/// assert_eq!(rdr.peek(1).unwrap().len(), 0);
|
||||
/// ```
|
||||
#[unstable(feature = "bufreader_peek", issue = "128405")]
|
||||
|
||||
@@ -109,8 +109,8 @@ pub fn unconsume(&mut self, amt: usize) {
|
||||
|
||||
/// Read more bytes into the buffer without discarding any of its contents
|
||||
pub fn read_more(&mut self, mut reader: impl Read) -> io::Result<usize> {
|
||||
let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]);
|
||||
let old_init = self.initialized - self.pos;
|
||||
let mut buf = BorrowedBuf::from(&mut self.buf[self.filled..]);
|
||||
let old_init = self.initialized - self.filled;
|
||||
unsafe {
|
||||
buf.set_init(old_init);
|
||||
}
|
||||
|
||||
@@ -439,6 +439,27 @@ fn slice_write_vectored(
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> {
|
||||
let n = slice_write(pos_mut, slice, buf)?;
|
||||
if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_write_all_vectored(
|
||||
pos_mut: &mut u64,
|
||||
slice: &mut [u8],
|
||||
bufs: &[IoSlice<'_>],
|
||||
) -> io::Result<()> {
|
||||
for buf in bufs {
|
||||
let n = slice_write(pos_mut, slice, buf)?;
|
||||
if n < buf.len() {
|
||||
return Err(io::Error::WRITE_ALL_EOF);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reserves the required space, and pads the vec with 0s if necessary.
|
||||
fn reserve_and_pad<A: Allocator>(
|
||||
pos_mut: &mut u64,
|
||||
@@ -481,9 +502,12 @@ fn reserve_and_pad<A: Allocator>(
|
||||
Ok(pos)
|
||||
}
|
||||
|
||||
/// Writes the slice to the vec without allocating
|
||||
/// # Safety: vec must have buf.len() spare capacity
|
||||
unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
|
||||
/// Writes the slice to the vec without allocating.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `vec` must have `buf.len()` spare capacity.
|
||||
unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
|
||||
where
|
||||
A: Allocator,
|
||||
{
|
||||
@@ -492,7 +516,7 @@ unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -
|
||||
pos + buf.len()
|
||||
}
|
||||
|
||||
/// Resizing write implementation for [`Cursor`]
|
||||
/// Resizing `write_all` implementation for [`Cursor`].
|
||||
///
|
||||
/// Cursor is allowed to have a pre-allocated and initialised
|
||||
/// vector body, but with a position of 0. This means the [`Write`]
|
||||
@@ -501,7 +525,7 @@ unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -
|
||||
/// This also allows for the vec body to be empty, but with a position of N.
|
||||
/// This means that [`Write`] will pad the vec with 0 initially,
|
||||
/// before writing anything from that point
|
||||
fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
|
||||
fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
|
||||
where
|
||||
A: Allocator,
|
||||
{
|
||||
@@ -512,7 +536,7 @@ fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Resu
|
||||
// Safety: we have ensured that the capacity is available
|
||||
// and that all bytes get written up to pos
|
||||
unsafe {
|
||||
pos = vec_write_unchecked(pos, vec, buf);
|
||||
pos = vec_write_all_unchecked(pos, vec, buf);
|
||||
if pos > vec.len() {
|
||||
vec.set_len(pos);
|
||||
}
|
||||
@@ -523,7 +547,7 @@ fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Resu
|
||||
Ok(buf_len)
|
||||
}
|
||||
|
||||
/// Resizing write_vectored implementation for [`Cursor`]
|
||||
/// Resizing `write_all_vectored` implementation for [`Cursor`].
|
||||
///
|
||||
/// Cursor is allowed to have a pre-allocated and initialised
|
||||
/// vector body, but with a position of 0. This means the [`Write`]
|
||||
@@ -532,7 +556,7 @@ fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Resu
|
||||
/// This also allows for the vec body to be empty, but with a position of N.
|
||||
/// This means that [`Write`] will pad the vec with 0 initially,
|
||||
/// before writing anything from that point
|
||||
fn vec_write_vectored<A>(
|
||||
fn vec_write_all_vectored<A>(
|
||||
pos_mut: &mut u64,
|
||||
vec: &mut Vec<u8, A>,
|
||||
bufs: &[IoSlice<'_>],
|
||||
@@ -550,7 +574,7 @@ fn vec_write_vectored<A>(
|
||||
// and that all bytes get written up to the last pos
|
||||
unsafe {
|
||||
for buf in bufs {
|
||||
pos = vec_write_unchecked(pos, vec, buf);
|
||||
pos = vec_write_all_unchecked(pos, vec, buf);
|
||||
}
|
||||
if pos > vec.len() {
|
||||
vec.set_len(pos);
|
||||
@@ -579,6 +603,16 @@ fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
slice_write_all(&mut self.pos, self.inner, buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
slice_write_all_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@@ -591,11 +625,11 @@ impl<A> Write for Cursor<&mut Vec<u8, A>>
|
||||
A: Allocator,
|
||||
{
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
vec_write(&mut self.pos, self.inner, buf)
|
||||
vec_write_all(&mut self.pos, self.inner, buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
vec_write_vectored(&mut self.pos, self.inner, bufs)
|
||||
vec_write_all_vectored(&mut self.pos, self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -603,6 +637,16 @@ fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
vec_write_all(&mut self.pos, self.inner, buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
vec_write_all_vectored(&mut self.pos, self.inner, bufs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@@ -615,11 +659,11 @@ impl<A> Write for Cursor<Vec<u8, A>>
|
||||
A: Allocator,
|
||||
{
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
vec_write(&mut self.pos, &mut self.inner, buf)
|
||||
vec_write_all(&mut self.pos, &mut self.inner, buf)
|
||||
}
|
||||
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -627,6 +671,16 @@ fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
vec_write_all(&mut self.pos, &mut self.inner, buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@@ -653,6 +707,16 @@ fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
slice_write_all(&mut self.pos, &mut self.inner, buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@@ -676,6 +740,16 @@ fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
slice_write_all(&mut self.pos, &mut self.inner, buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
|
||||
+69
-11
@@ -455,7 +455,17 @@ fn is_write_vectored(&self) -> bool {
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
|
||||
if self.write(data)? == data.len() { Ok(()) } else { Err(io::Error::WRITE_ALL_EOF) }
|
||||
if self.write(data)? < data.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
for buf in bufs {
|
||||
if self.write(buf)? < buf.len() {
|
||||
return Err(io::Error::WRITE_ALL_EOF);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -495,6 +505,12 @@ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
self.write_vectored(bufs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
@@ -515,6 +531,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||
let (front, back) = self.as_slices();
|
||||
|
||||
@@ -547,6 +564,7 @@ fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
|
||||
let len = cursor.capacity();
|
||||
let (front, back) = self.as_slices();
|
||||
@@ -639,18 +657,58 @@ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
self.write_vectored(bufs)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "read_buf", issue = "78485")]
|
||||
impl<'a> io::Write for core::io::BorrowedCursor<'a> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let amt = cmp::min(buf.len(), self.capacity());
|
||||
self.append(&buf[..amt]);
|
||||
Ok(amt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
let mut nwritten = 0;
|
||||
for buf in bufs {
|
||||
let n = self.write(buf)?;
|
||||
nwritten += n;
|
||||
if n < buf.len() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
if self.write(buf)? < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
|
||||
for buf in bufs {
|
||||
if self.write(buf)? < buf.len() {
|
||||
return Err(io::Error::WRITE_ALL_EOF);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "read_buf", issue = "78485")]
|
||||
impl<'a> io::Write for core::io::BorrowedCursor<'a> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let amt = cmp::min(buf.len(), self.capacity());
|
||||
self.append(&buf[..amt]);
|
||||
Ok(amt)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
|
||||
@@ -139,6 +139,11 @@ pub fn push_slice(&mut self, s: &Slice) {
|
||||
self.inner.extend_from_slice(&s.inner)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push_str(&mut self, s: &str) {
|
||||
self.inner.extend_from_slice(s.as_bytes());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.inner.reserve(additional)
|
||||
|
||||
@@ -116,6 +116,11 @@ pub fn push_slice(&mut self, s: &Slice) {
|
||||
self.inner.push_wtf8(&s.inner)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push_str(&mut self, s: &str) {
|
||||
self.inner.push_str(s);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.inner.reserve(additional)
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// MIR for `demo_le` after PreCodegen
|
||||
|
||||
fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
|
||||
debug a => _1;
|
||||
debug b => _2;
|
||||
let mut _0: bool;
|
||||
scope 1 (inlined <MultiField as PartialOrd>::le) {
|
||||
let mut _11: std::option::Option<std::cmp::Ordering>;
|
||||
scope 2 (inlined Option::<std::cmp::Ordering>::is_some_and::<fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le}>) {
|
||||
let _12: std::cmp::Ordering;
|
||||
scope 3 {
|
||||
scope 4 (inlined <fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) {
|
||||
scope 5 (inlined std::cmp::Ordering::is_le) {
|
||||
let mut _13: i8;
|
||||
scope 6 (inlined std::cmp::Ordering::as_raw) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 7 (inlined <MultiField as PartialOrd>::partial_cmp) {
|
||||
let mut _6: std::option::Option<std::cmp::Ordering>;
|
||||
let mut _7: i8;
|
||||
scope 8 {
|
||||
}
|
||||
scope 9 (inlined std::cmp::impls::<impl PartialOrd for char>::partial_cmp) {
|
||||
let mut _3: char;
|
||||
let mut _4: char;
|
||||
let mut _5: std::cmp::Ordering;
|
||||
}
|
||||
scope 10 (inlined std::cmp::impls::<impl PartialOrd for i16>::partial_cmp) {
|
||||
let mut _8: i16;
|
||||
let mut _9: i16;
|
||||
let mut _10: std::cmp::Ordering;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_12);
|
||||
StorageLive(_11);
|
||||
StorageLive(_5);
|
||||
StorageLive(_7);
|
||||
StorageLive(_3);
|
||||
_3 = copy ((*_1).0: char);
|
||||
StorageLive(_4);
|
||||
_4 = copy ((*_2).0: char);
|
||||
_5 = Cmp(move _3, move _4);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
_6 = Option::<std::cmp::Ordering>::Some(copy _5);
|
||||
_7 = discriminant(_5);
|
||||
switchInt(move _7) -> [0: bb1, otherwise: bb2];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_10);
|
||||
StorageLive(_8);
|
||||
_8 = copy ((*_1).1: i16);
|
||||
StorageLive(_9);
|
||||
_9 = copy ((*_2).1: i16);
|
||||
_10 = Cmp(move _8, move _9);
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
_11 = Option::<std::cmp::Ordering>::Some(move _10);
|
||||
StorageDead(_10);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
_11 = copy _6;
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_12 = move ((_11 as Some).0: std::cmp::Ordering);
|
||||
StorageLive(_13);
|
||||
_13 = discriminant(_12);
|
||||
_0 = Le(move _13, const 0_i8);
|
||||
StorageDead(_13);
|
||||
StorageDead(_11);
|
||||
StorageDead(_12);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// skip-filecheck
|
||||
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
@@ -6,4 +5,29 @@
|
||||
#[derive(PartialOrd, PartialEq)]
|
||||
pub struct MultiField(char, i16);
|
||||
|
||||
// Because this isn't derived by the impl, it's not on the `{impl#0}-partial_cmp`,
|
||||
// and thus we need to call it to see what the inlined generic one produces.
|
||||
pub fn demo_le(a: &MultiField, b: &MultiField) -> bool {
|
||||
// CHECK-LABEL: fn demo_le
|
||||
// CHECK: inlined <MultiField as PartialOrd>::le
|
||||
// CHECK: inlined{{.+}}is_some_and
|
||||
// CHECK: inlined <MultiField as PartialOrd>::partial_cmp
|
||||
|
||||
// CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char);
|
||||
// CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char);
|
||||
// CHECK: Cmp(move [[A0]], move [[B0]]);
|
||||
|
||||
// CHECK: [[D0:_[0-9]+]] = discriminant({{.+}});
|
||||
// CHECK: switchInt(move [[D0]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}];
|
||||
|
||||
// CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16);
|
||||
// CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16);
|
||||
// CHECK: Cmp(move [[A1]], move [[B1]]);
|
||||
|
||||
// CHECK: [[D1:_[0-9]+]] = discriminant({{.+}});
|
||||
// CHECK: _0 = Le(move [[D1]], const 0_i8);
|
||||
*a <= *b
|
||||
}
|
||||
|
||||
// EMIT_MIR derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir
|
||||
// EMIT_MIR derived_ord.demo_le.PreCodegen.after.mir
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIR for `<impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp` after PreCodegen
|
||||
// MIR for `<impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp` after PreCodegen
|
||||
|
||||
fn <impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
|
||||
fn <impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
|
||||
debug self => _1;
|
||||
debug other => _2;
|
||||
let mut _0: std::option::Option<std::cmp::Ordering>;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fn stati<T: 'stati>() {}
|
||||
//~^ ERROR use of undeclared lifetime name `'stati`
|
||||
|
||||
fn statoc<T: 'statoc>() {}
|
||||
//~^ ERROR use of undeclared lifetime name `'statoc`
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,26 @@
|
||||
error[E0261]: use of undeclared lifetime name `'stati`
|
||||
--> $DIR/static-typos.rs:1:13
|
||||
|
|
||||
LL | fn stati<T: 'stati>() {}
|
||||
| ^^^^^^ undeclared lifetime
|
||||
|
|
||||
help: you may have misspelled the `'static` lifetime
|
||||
|
|
||||
LL | fn stati<T: 'static>() {}
|
||||
| +
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'statoc`
|
||||
--> $DIR/static-typos.rs:4:14
|
||||
|
|
||||
LL | fn statoc<T: 'statoc>() {}
|
||||
| ^^^^^^^ undeclared lifetime
|
||||
|
|
||||
help: you may have misspelled the `'static` lifetime
|
||||
|
|
||||
LL - fn statoc<T: 'statoc>() {}
|
||||
LL + fn statoc<T: 'static>() {}
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
Reference in New Issue
Block a user