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:
bors
2025-03-07 10:40:12 +00:00
19 changed files with 441 additions and 79 deletions
+1 -3
View File
@@ -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)
+30 -18
View File
@@ -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();
}
+2 -2
View File
@@ -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
View File
@@ -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`.
+6 -2
View File
@@ -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",
+8 -8
View File
@@ -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;
}
+48 -2
View File
@@ -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]&lt;[OsStr]&gt;</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()
}
}
+3 -3
View File
@@ -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);
}
+87 -13
View File
@@ -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
View File
@@ -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<()> {
+5
View File
@@ -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)
+5
View File
@@ -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;
}
}
+25 -1
View File
@@ -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>;
+7
View File
@@ -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() {}
+26
View File
@@ -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`.