Skip to content

Commit 59a9b9e

Browse files
committedMar 7, 2025·
Auto merge of rust-lang#138151 - matthiaskrgr:rollup-j0p6ed1, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#136667 (Revert vita's c_char back to i8) - rust-lang#137107 (Override default `Write` methods for cursor-like types) - rust-lang#137777 (Specialize `OsString::push` and `OsString as From` for UTF-8) - rust-lang#137832 (Fix crash in BufReader::peek()) - rust-lang#137904 (Improve the generic MIR in the default `PartialOrd::le` and friends) - rust-lang#138115 (Suggest typo fix for static lifetime) - rust-lang#138125 (Simplify `printf` and shell format suggestions) - rust-lang#138129 (Stabilize const_char_classify, const_sockaddr_setters) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 91a0e16 + c33e9d6 commit 59a9b9e

File tree

19 files changed

+431
-69
lines changed

19 files changed

+431
-69
lines changed
 

‎compiler/rustc_builtin_macros/src/format.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -711,11 +711,9 @@ fn report_missing_placeholders(
711711
};
712712

713713
let pos = sub.position();
714-
let sub = String::from(sub.as_str());
715-
if explained.contains(&sub) {
714+
if !explained.insert(sub.to_string()) {
716715
continue;
717716
}
718-
explained.insert(sub);
719717

720718
if !found_foreign {
721719
found_foreign = true;

‎compiler/rustc_builtin_macros/src/format_foreign.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ pub(crate) mod printf {
1212
Escape((usize, usize)),
1313
}
1414

15-
impl<'a> Substitution<'a> {
16-
pub(crate) fn as_str(&self) -> &str {
15+
impl ToString for Substitution<'_> {
16+
fn to_string(&self) -> String {
1717
match self {
18-
Substitution::Format(fmt) => fmt.span,
19-
Substitution::Escape(_) => "%%",
18+
Substitution::Format(fmt) => fmt.span.into(),
19+
Substitution::Escape(_) => "%%".into(),
2020
}
2121
}
22+
}
2223

24+
impl Substitution<'_> {
2325
pub(crate) fn position(&self) -> InnerSpan {
2426
match self {
2527
Substitution::Format(fmt) => fmt.position,
@@ -627,15 +629,17 @@ pub(crate) mod shell {
627629
Escape((usize, usize)),
628630
}
629631

630-
impl Substitution<'_> {
631-
pub(crate) fn as_str(&self) -> String {
632+
impl ToString for Substitution<'_> {
633+
fn to_string(&self) -> String {
632634
match self {
633635
Substitution::Ordinal(n, _) => format!("${n}"),
634636
Substitution::Name(n, _) => format!("${n}"),
635637
Substitution::Escape(_) => "$$".into(),
636638
}
637639
}
640+
}
638641

642+
impl Substitution<'_> {
639643
pub(crate) fn position(&self) -> InnerSpan {
640644
let (Self::Ordinal(_, pos) | Self::Name(_, pos) | Self::Escape(pos)) = self;
641645
InnerSpan::new(pos.0, pos.1)

‎compiler/rustc_resolve/src/late/diagnostics.rs

+30-18
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
2424
use rustc_hir::{MissingLifetimeKind, PrimTy};
2525
use rustc_middle::ty;
2626
use rustc_session::{Session, lint};
27-
use rustc_span::edit_distance::find_best_match_for_name;
27+
use rustc_span::edit_distance::{edit_distance, find_best_match_for_name};
2828
use rustc_span::edition::Edition;
2929
use rustc_span::hygiene::MacroKind;
3030
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
@@ -2919,23 +2919,35 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
29192919
)
29202920
.with_span_label(lifetime_ref.ident.span, "undeclared lifetime")
29212921
};
2922-
self.suggest_introducing_lifetime(
2923-
&mut err,
2924-
Some(lifetime_ref.ident.name.as_str()),
2925-
|err, _, span, message, suggestion, span_suggs| {
2926-
err.multipart_suggestion_with_style(
2927-
message,
2928-
std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(),
2929-
Applicability::MaybeIncorrect,
2930-
if span_suggs.is_empty() {
2931-
SuggestionStyle::ShowCode
2932-
} else {
2933-
SuggestionStyle::ShowAlways
2934-
},
2935-
);
2936-
true
2937-
},
2938-
);
2922+
2923+
// Check if this is a typo of `'static`.
2924+
if edit_distance(lifetime_ref.ident.name.as_str(), "'static", 2).is_some() {
2925+
err.span_suggestion_verbose(
2926+
lifetime_ref.ident.span,
2927+
"you may have misspelled the `'static` lifetime",
2928+
"'static",
2929+
Applicability::MachineApplicable,
2930+
);
2931+
} else {
2932+
self.suggest_introducing_lifetime(
2933+
&mut err,
2934+
Some(lifetime_ref.ident.name.as_str()),
2935+
|err, _, span, message, suggestion, span_suggs| {
2936+
err.multipart_suggestion_with_style(
2937+
message,
2938+
std::iter::once((span, suggestion)).chain(span_suggs.clone()).collect(),
2939+
Applicability::MaybeIncorrect,
2940+
if span_suggs.is_empty() {
2941+
SuggestionStyle::ShowCode
2942+
} else {
2943+
SuggestionStyle::ShowAlways
2944+
},
2945+
);
2946+
true
2947+
},
2948+
);
2949+
}
2950+
29392951
err.emit();
29402952
}
29412953

‎library/core/src/char/methods.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl char {
337337
/// '1'.is_digit(1);
338338
/// ```
339339
#[stable(feature = "rust1", since = "1.0.0")]
340-
#[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
340+
#[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
341341
#[inline]
342342
pub const fn is_digit(self, radix: u32) -> bool {
343343
self.to_digit(radix).is_some()
@@ -886,7 +886,7 @@ impl char {
886886
/// ```
887887
#[must_use]
888888
#[stable(feature = "rust1", since = "1.0.0")]
889-
#[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
889+
#[rustc_const_stable(feature = "const_char_classify", since = "CURRENT_RUSTC_VERSION")]
890890
#[inline]
891891
pub const fn is_whitespace(self) -> bool {
892892
match self {

‎library/core/src/cmp.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ pub enum Ordering {
397397
}
398398

399399
impl Ordering {
400+
#[inline]
401+
const fn as_raw(self) -> i8 {
402+
// FIXME(const-hack): just use `PartialOrd` against `Equal` once that's const
403+
crate::intrinsics::discriminant_value(&self)
404+
}
405+
400406
/// Returns `true` if the ordering is the `Equal` variant.
401407
///
402408
/// # Examples
@@ -413,7 +419,11 @@ impl Ordering {
413419
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
414420
#[stable(feature = "ordering_helpers", since = "1.53.0")]
415421
pub const fn is_eq(self) -> bool {
416-
matches!(self, Equal)
422+
// All the `is_*` methods are implemented as comparisons against zero
423+
// to follow how clang's libcxx implements their equivalents in
424+
// <https://github.com/llvm/llvm-project/blob/60486292b79885b7800b082754153202bef5b1f0/libcxx/include/__compare/is_eq.h#L23-L28>
425+
426+
self.as_raw() == 0
417427
}
418428

419429
/// Returns `true` if the ordering is not the `Equal` variant.
@@ -432,7 +442,7 @@ impl Ordering {
432442
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
433443
#[stable(feature = "ordering_helpers", since = "1.53.0")]
434444
pub const fn is_ne(self) -> bool {
435-
!matches!(self, Equal)
445+
self.as_raw() != 0
436446
}
437447

438448
/// Returns `true` if the ordering is the `Less` variant.
@@ -451,7 +461,7 @@ impl Ordering {
451461
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
452462
#[stable(feature = "ordering_helpers", since = "1.53.0")]
453463
pub const fn is_lt(self) -> bool {
454-
matches!(self, Less)
464+
self.as_raw() < 0
455465
}
456466

457467
/// Returns `true` if the ordering is the `Greater` variant.
@@ -470,7 +480,7 @@ impl Ordering {
470480
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
471481
#[stable(feature = "ordering_helpers", since = "1.53.0")]
472482
pub const fn is_gt(self) -> bool {
473-
matches!(self, Greater)
483+
self.as_raw() > 0
474484
}
475485

476486
/// Returns `true` if the ordering is either the `Less` or `Equal` variant.
@@ -489,7 +499,7 @@ impl Ordering {
489499
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
490500
#[stable(feature = "ordering_helpers", since = "1.53.0")]
491501
pub const fn is_le(self) -> bool {
492-
!matches!(self, Greater)
502+
self.as_raw() <= 0
493503
}
494504

495505
/// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
@@ -508,7 +518,7 @@ impl Ordering {
508518
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
509519
#[stable(feature = "ordering_helpers", since = "1.53.0")]
510520
pub const fn is_ge(self) -> bool {
511-
!matches!(self, Less)
521+
self.as_raw() >= 0
512522
}
513523

514524
/// Reverses the `Ordering`.

‎library/core/src/ffi/primitives.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ mod c_char_definition {
3939
// These are the targets on which c_char is unsigned. Usually the
4040
// signedness is the same for all target_os values on a given architecture
4141
// but there are some exceptions (see isSignedCharDefault() in clang).
42-
//
4342
// aarch64:
4443
// Section 10 "Arm C and C++ language mappings" in Procedure Call Standard for the Arm®
4544
// 64-bit Architecture (AArch64) says C/C++ char is unsigned byte.
@@ -97,14 +96,19 @@ mod c_char_definition {
9796
// are promoted to int as if from type signed char by default, unless the /J compilation
9897
// option is used."
9998
// https://learn.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=msvc-170#character-types
99+
// Vita:
100+
// Chars are signed by default on the Vita, and VITASDK follows that convention.
101+
// https://github.com/vitasdk/buildscripts/blob/09c533b771591ecde88864b6acad28ffb688dbd4/patches/gcc/0001-gcc-10.patch#L33-L34
102+
//
100103
// L4Re:
101-
// The kernel builds with -funsigned-char on all targets (but useserspace follows the
104+
// The kernel builds with -funsigned-char on all targets (but userspace follows the
102105
// architecture defaults). As we only have a target for userspace apps so there are no
103106
// special cases for L4Re below.
104107
// https://github.com/rust-lang/rust/pull/132975#issuecomment-2484645240
105108
if #[cfg(all(
106109
not(windows),
107110
not(target_vendor = "apple"),
111+
not(target_os = "vita"),
108112
any(
109113
target_arch = "aarch64",
110114
target_arch = "arm",

‎library/core/src/net/socket_addr.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl SocketAddr {
200200
/// ```
201201
#[inline]
202202
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
203-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
203+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
204204
pub const fn set_ip(&mut self, new_ip: IpAddr) {
205205
// `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
206206
match (self, new_ip) {
@@ -244,7 +244,7 @@ impl SocketAddr {
244244
/// ```
245245
#[inline]
246246
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
247-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
247+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
248248
pub const fn set_port(&mut self, new_port: u16) {
249249
match *self {
250250
SocketAddr::V4(ref mut a) => a.set_port(new_port),
@@ -350,7 +350,7 @@ impl SocketAddrV4 {
350350
/// ```
351351
#[inline]
352352
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
353-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
353+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
354354
pub const fn set_ip(&mut self, new_ip: Ipv4Addr) {
355355
self.ip = new_ip;
356356
}
@@ -386,7 +386,7 @@ impl SocketAddrV4 {
386386
/// ```
387387
#[inline]
388388
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
389-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
389+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
390390
pub const fn set_port(&mut self, new_port: u16) {
391391
self.port = new_port;
392392
}
@@ -448,7 +448,7 @@ impl SocketAddrV6 {
448448
/// ```
449449
#[inline]
450450
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
451-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
451+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
452452
pub const fn set_ip(&mut self, new_ip: Ipv6Addr) {
453453
self.ip = new_ip;
454454
}
@@ -484,7 +484,7 @@ impl SocketAddrV6 {
484484
/// ```
485485
#[inline]
486486
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
487-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
487+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
488488
pub const fn set_port(&mut self, new_port: u16) {
489489
self.port = new_port;
490490
}
@@ -532,7 +532,7 @@ impl SocketAddrV6 {
532532
/// ```
533533
#[inline]
534534
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
535-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
535+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
536536
pub const fn set_flowinfo(&mut self, new_flowinfo: u32) {
537537
self.flowinfo = new_flowinfo;
538538
}
@@ -575,7 +575,7 @@ impl SocketAddrV6 {
575575
/// ```
576576
#[inline]
577577
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
578-
#[rustc_const_unstable(feature = "const_sockaddr_setters", issue = "131714")]
578+
#[rustc_const_stable(feature = "const_sockaddr_setters", since = "CURRENT_RUSTC_VERSION")]
579579
pub const fn set_scope_id(&mut self, new_scope_id: u32) {
580580
self.scope_id = new_scope_id;
581581
}

‎library/std/src/ffi/os_str.rs

+48-2
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,30 @@ impl OsString {
257257
#[inline]
258258
#[rustc_confusables("append", "put")]
259259
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
260-
self.inner.push_slice(&s.as_ref().inner)
260+
trait SpecPushTo {
261+
fn spec_push_to(&self, buf: &mut OsString);
262+
}
263+
264+
impl<T: AsRef<OsStr>> SpecPushTo for T {
265+
#[inline]
266+
default fn spec_push_to(&self, buf: &mut OsString) {
267+
buf.inner.push_slice(&self.as_ref().inner);
268+
}
269+
}
270+
271+
// Use a more efficient implementation when the string is UTF-8.
272+
macro spec_str($T:ty) {
273+
impl SpecPushTo for $T {
274+
#[inline]
275+
fn spec_push_to(&self, buf: &mut OsString) {
276+
buf.inner.push_str(self);
277+
}
278+
}
279+
}
280+
spec_str!(str);
281+
spec_str!(String);
282+
283+
s.spec_push_to(self)
261284
}
262285

263286
/// Creates a new `OsString` with at least the given capacity.
@@ -587,7 +610,30 @@ impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
587610
/// Copies any value implementing <code>[AsRef]&lt;[OsStr]&gt;</code>
588611
/// into a newly allocated [`OsString`].
589612
fn from(s: &T) -> OsString {
590-
s.as_ref().to_os_string()
613+
trait SpecToOsString {
614+
fn spec_to_os_string(&self) -> OsString;
615+
}
616+
617+
impl<T: AsRef<OsStr>> SpecToOsString for T {
618+
#[inline]
619+
default fn spec_to_os_string(&self) -> OsString {
620+
self.as_ref().to_os_string()
621+
}
622+
}
623+
624+
// Preserve the known-UTF-8 property for strings.
625+
macro spec_str($T:ty) {
626+
impl SpecToOsString for $T {
627+
#[inline]
628+
fn spec_to_os_string(&self) -> OsString {
629+
OsString::from(String::from(self))
630+
}
631+
}
632+
}
633+
spec_str!(str);
634+
spec_str!(String);
635+
636+
s.spec_to_os_string()
591637
}
592638
}
593639

‎library/std/src/io/buffered/bufreader.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,16 @@ impl<R: Read + ?Sized> BufReader<R> {
118118
/// #![feature(bufreader_peek)]
119119
/// use std::io::{Read, BufReader};
120120
///
121-
/// let mut bytes = &b"oh, hello"[..];
121+
/// let mut bytes = &b"oh, hello there"[..];
122122
/// let mut rdr = BufReader::with_capacity(6, &mut bytes);
123123
/// assert_eq!(rdr.peek(2).unwrap(), b"oh");
124124
/// let mut buf = [0; 4];
125125
/// rdr.read(&mut buf[..]).unwrap();
126126
/// assert_eq!(&buf, b"oh, ");
127-
/// assert_eq!(rdr.peek(2).unwrap(), b"he");
127+
/// assert_eq!(rdr.peek(5).unwrap(), b"hello");
128128
/// let mut s = String::new();
129129
/// rdr.read_to_string(&mut s).unwrap();
130-
/// assert_eq!(&s, "hello");
130+
/// assert_eq!(&s, "hello there");
131131
/// assert_eq!(rdr.peek(1).unwrap().len(), 0);
132132
/// ```
133133
#[unstable(feature = "bufreader_peek", issue = "128405")]

‎library/std/src/io/buffered/bufreader/buffer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ impl Buffer {
109109

110110
/// Read more bytes into the buffer without discarding any of its contents
111111
pub fn read_more(&mut self, mut reader: impl Read) -> io::Result<usize> {
112-
let mut buf = BorrowedBuf::from(&mut self.buf[self.pos..]);
113-
let old_init = self.initialized - self.pos;
112+
let mut buf = BorrowedBuf::from(&mut self.buf[self.filled..]);
113+
let old_init = self.initialized - self.filled;
114114
unsafe {
115115
buf.set_init(old_init);
116116
}

‎library/std/src/io/cursor.rs

+87-13
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,27 @@ fn slice_write_vectored(
439439
Ok(nwritten)
440440
}
441441

442+
#[inline]
443+
fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> {
444+
let n = slice_write(pos_mut, slice, buf)?;
445+
if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
446+
}
447+
448+
#[inline]
449+
fn slice_write_all_vectored(
450+
pos_mut: &mut u64,
451+
slice: &mut [u8],
452+
bufs: &[IoSlice<'_>],
453+
) -> io::Result<()> {
454+
for buf in bufs {
455+
let n = slice_write(pos_mut, slice, buf)?;
456+
if n < buf.len() {
457+
return Err(io::Error::WRITE_ALL_EOF);
458+
}
459+
}
460+
Ok(())
461+
}
462+
442463
/// Reserves the required space, and pads the vec with 0s if necessary.
443464
fn reserve_and_pad<A: Allocator>(
444465
pos_mut: &mut u64,
@@ -481,9 +502,12 @@ fn reserve_and_pad<A: Allocator>(
481502
Ok(pos)
482503
}
483504

484-
/// Writes the slice to the vec without allocating
485-
/// # Safety: vec must have buf.len() spare capacity
486-
unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
505+
/// Writes the slice to the vec without allocating.
506+
///
507+
/// # Safety
508+
///
509+
/// `vec` must have `buf.len()` spare capacity.
510+
unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
487511
where
488512
A: Allocator,
489513
{
@@ -492,7 +516,7 @@ where
492516
pos + buf.len()
493517
}
494518

495-
/// Resizing write implementation for [`Cursor`]
519+
/// Resizing `write_all` implementation for [`Cursor`].
496520
///
497521
/// Cursor is allowed to have a pre-allocated and initialised
498522
/// vector body, but with a position of 0. This means the [`Write`]
@@ -501,7 +525,7 @@ where
501525
/// This also allows for the vec body to be empty, but with a position of N.
502526
/// This means that [`Write`] will pad the vec with 0 initially,
503527
/// before writing anything from that point
504-
fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
528+
fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
505529
where
506530
A: Allocator,
507531
{
@@ -512,7 +536,7 @@ where
512536
// Safety: we have ensured that the capacity is available
513537
// and that all bytes get written up to pos
514538
unsafe {
515-
pos = vec_write_unchecked(pos, vec, buf);
539+
pos = vec_write_all_unchecked(pos, vec, buf);
516540
if pos > vec.len() {
517541
vec.set_len(pos);
518542
}
@@ -523,7 +547,7 @@ where
523547
Ok(buf_len)
524548
}
525549

526-
/// Resizing write_vectored implementation for [`Cursor`]
550+
/// Resizing `write_all_vectored` implementation for [`Cursor`].
527551
///
528552
/// Cursor is allowed to have a pre-allocated and initialised
529553
/// vector body, but with a position of 0. This means the [`Write`]
@@ -532,7 +556,7 @@ where
532556
/// This also allows for the vec body to be empty, but with a position of N.
533557
/// This means that [`Write`] will pad the vec with 0 initially,
534558
/// before writing anything from that point
535-
fn vec_write_vectored<A>(
559+
fn vec_write_all_vectored<A>(
536560
pos_mut: &mut u64,
537561
vec: &mut Vec<u8, A>,
538562
bufs: &[IoSlice<'_>],
@@ -550,7 +574,7 @@ where
550574
// and that all bytes get written up to the last pos
551575
unsafe {
552576
for buf in bufs {
553-
pos = vec_write_unchecked(pos, vec, buf);
577+
pos = vec_write_all_unchecked(pos, vec, buf);
554578
}
555579
if pos > vec.len() {
556580
vec.set_len(pos);
@@ -579,6 +603,16 @@ impl Write for Cursor<&mut [u8]> {
579603
true
580604
}
581605

606+
#[inline]
607+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
608+
slice_write_all(&mut self.pos, self.inner, buf)
609+
}
610+
611+
#[inline]
612+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
613+
slice_write_all_vectored(&mut self.pos, self.inner, bufs)
614+
}
615+
582616
#[inline]
583617
fn flush(&mut self) -> io::Result<()> {
584618
Ok(())
@@ -591,18 +625,28 @@ where
591625
A: Allocator,
592626
{
593627
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
594-
vec_write(&mut self.pos, self.inner, buf)
628+
vec_write_all(&mut self.pos, self.inner, buf)
595629
}
596630

597631
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
598-
vec_write_vectored(&mut self.pos, self.inner, bufs)
632+
vec_write_all_vectored(&mut self.pos, self.inner, bufs)
599633
}
600634

601635
#[inline]
602636
fn is_write_vectored(&self) -> bool {
603637
true
604638
}
605639

640+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
641+
vec_write_all(&mut self.pos, self.inner, buf)?;
642+
Ok(())
643+
}
644+
645+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
646+
vec_write_all_vectored(&mut self.pos, self.inner, bufs)?;
647+
Ok(())
648+
}
649+
606650
#[inline]
607651
fn flush(&mut self) -> io::Result<()> {
608652
Ok(())
@@ -615,18 +659,28 @@ where
615659
A: Allocator,
616660
{
617661
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
618-
vec_write(&mut self.pos, &mut self.inner, buf)
662+
vec_write_all(&mut self.pos, &mut self.inner, buf)
619663
}
620664

621665
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
622-
vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
666+
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
623667
}
624668

625669
#[inline]
626670
fn is_write_vectored(&self) -> bool {
627671
true
628672
}
629673

674+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
675+
vec_write_all(&mut self.pos, &mut self.inner, buf)?;
676+
Ok(())
677+
}
678+
679+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
680+
vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?;
681+
Ok(())
682+
}
683+
630684
#[inline]
631685
fn flush(&mut self) -> io::Result<()> {
632686
Ok(())
@@ -653,6 +707,16 @@ where
653707
true
654708
}
655709

710+
#[inline]
711+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
712+
slice_write_all(&mut self.pos, &mut self.inner, buf)
713+
}
714+
715+
#[inline]
716+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
717+
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
718+
}
719+
656720
#[inline]
657721
fn flush(&mut self) -> io::Result<()> {
658722
Ok(())
@@ -676,6 +740,16 @@ impl<const N: usize> Write for Cursor<[u8; N]> {
676740
true
677741
}
678742

743+
#[inline]
744+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
745+
slice_write_all(&mut self.pos, &mut self.inner, buf)
746+
}
747+
748+
#[inline]
749+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
750+
slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
751+
}
752+
679753
#[inline]
680754
fn flush(&mut self) -> io::Result<()> {
681755
Ok(())

‎library/std/src/io/impls.rs

+59-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,17 @@ impl Write for &mut [u8] {
455455

456456
#[inline]
457457
fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
458-
if self.write(data)? == data.len() { Ok(()) } else { Err(io::Error::WRITE_ALL_EOF) }
458+
if self.write(data)? < data.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
459+
}
460+
461+
#[inline]
462+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
463+
for buf in bufs {
464+
if self.write(buf)? < buf.len() {
465+
return Err(io::Error::WRITE_ALL_EOF);
466+
}
467+
}
468+
Ok(())
459469
}
460470

461471
#[inline]
@@ -495,6 +505,12 @@ impl<A: Allocator> Write for Vec<u8, A> {
495505
Ok(())
496506
}
497507

508+
#[inline]
509+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
510+
self.write_vectored(bufs)?;
511+
Ok(())
512+
}
513+
498514
#[inline]
499515
fn flush(&mut self) -> io::Result<()> {
500516
Ok(())
@@ -515,6 +531,7 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
515531
Ok(n)
516532
}
517533

534+
#[inline]
518535
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
519536
let (front, back) = self.as_slices();
520537

@@ -547,6 +564,7 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
547564
Ok(())
548565
}
549566

567+
#[inline]
550568
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
551569
let len = cursor.capacity();
552570
let (front, back) = self.as_slices();
@@ -638,6 +656,12 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
638656
Ok(())
639657
}
640658

659+
#[inline]
660+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
661+
self.write_vectored(bufs)?;
662+
Ok(())
663+
}
664+
641665
#[inline]
642666
fn flush(&mut self) -> io::Result<()> {
643667
Ok(())
@@ -646,12 +670,46 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
646670

647671
#[unstable(feature = "read_buf", issue = "78485")]
648672
impl<'a> io::Write for core::io::BorrowedCursor<'a> {
673+
#[inline]
649674
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
650675
let amt = cmp::min(buf.len(), self.capacity());
651676
self.append(&buf[..amt]);
652677
Ok(amt)
653678
}
654679

680+
#[inline]
681+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
682+
let mut nwritten = 0;
683+
for buf in bufs {
684+
let n = self.write(buf)?;
685+
nwritten += n;
686+
if n < buf.len() {
687+
break;
688+
}
689+
}
690+
Ok(nwritten)
691+
}
692+
693+
#[inline]
694+
fn is_write_vectored(&self) -> bool {
695+
true
696+
}
697+
698+
#[inline]
699+
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
700+
if self.write(buf)? < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
701+
}
702+
703+
#[inline]
704+
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
705+
for buf in bufs {
706+
if self.write(buf)? < buf.len() {
707+
return Err(io::Error::WRITE_ALL_EOF);
708+
}
709+
}
710+
Ok(())
711+
}
712+
655713
#[inline]
656714
fn flush(&mut self) -> io::Result<()> {
657715
Ok(())

‎library/std/src/sys/os_str/bytes.rs

+5
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ impl Buf {
139139
self.inner.extend_from_slice(&s.inner)
140140
}
141141

142+
#[inline]
143+
pub fn push_str(&mut self, s: &str) {
144+
self.inner.extend_from_slice(s.as_bytes());
145+
}
146+
142147
#[inline]
143148
pub fn reserve(&mut self, additional: usize) {
144149
self.inner.reserve(additional)

‎library/std/src/sys/os_str/wtf8.rs

+5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ impl Buf {
116116
self.inner.push_wtf8(&s.inner)
117117
}
118118

119+
#[inline]
120+
pub fn push_str(&mut self, s: &str) {
121+
self.inner.push_str(s);
122+
}
123+
119124
#[inline]
120125
pub fn reserve(&mut self, additional: usize) {
121126
self.inner.reserve(additional)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// MIR for `demo_le` after PreCodegen
2+
3+
fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
4+
debug a => _1;
5+
debug b => _2;
6+
let mut _0: bool;
7+
scope 1 (inlined <MultiField as PartialOrd>::le) {
8+
let mut _11: std::option::Option<std::cmp::Ordering>;
9+
scope 2 (inlined Option::<std::cmp::Ordering>::is_some_and::<fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le}>) {
10+
let _12: std::cmp::Ordering;
11+
scope 3 {
12+
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})) {
13+
scope 5 (inlined std::cmp::Ordering::is_le) {
14+
let mut _13: i8;
15+
scope 6 (inlined std::cmp::Ordering::as_raw) {
16+
}
17+
}
18+
}
19+
}
20+
}
21+
scope 7 (inlined <MultiField as PartialOrd>::partial_cmp) {
22+
let mut _6: std::option::Option<std::cmp::Ordering>;
23+
let mut _7: i8;
24+
scope 8 {
25+
}
26+
scope 9 (inlined std::cmp::impls::<impl PartialOrd for char>::partial_cmp) {
27+
let mut _3: char;
28+
let mut _4: char;
29+
let mut _5: std::cmp::Ordering;
30+
}
31+
scope 10 (inlined std::cmp::impls::<impl PartialOrd for i16>::partial_cmp) {
32+
let mut _8: i16;
33+
let mut _9: i16;
34+
let mut _10: std::cmp::Ordering;
35+
}
36+
}
37+
}
38+
39+
bb0: {
40+
StorageLive(_12);
41+
StorageLive(_11);
42+
StorageLive(_5);
43+
StorageLive(_7);
44+
StorageLive(_3);
45+
_3 = copy ((*_1).0: char);
46+
StorageLive(_4);
47+
_4 = copy ((*_2).0: char);
48+
_5 = Cmp(move _3, move _4);
49+
StorageDead(_4);
50+
StorageDead(_3);
51+
_6 = Option::<std::cmp::Ordering>::Some(copy _5);
52+
_7 = discriminant(_5);
53+
switchInt(move _7) -> [0: bb1, otherwise: bb2];
54+
}
55+
56+
bb1: {
57+
StorageLive(_10);
58+
StorageLive(_8);
59+
_8 = copy ((*_1).1: i16);
60+
StorageLive(_9);
61+
_9 = copy ((*_2).1: i16);
62+
_10 = Cmp(move _8, move _9);
63+
StorageDead(_9);
64+
StorageDead(_8);
65+
_11 = Option::<std::cmp::Ordering>::Some(move _10);
66+
StorageDead(_10);
67+
StorageDead(_7);
68+
StorageDead(_5);
69+
goto -> bb3;
70+
}
71+
72+
bb2: {
73+
_11 = copy _6;
74+
StorageDead(_7);
75+
StorageDead(_5);
76+
goto -> bb3;
77+
}
78+
79+
bb3: {
80+
_12 = move ((_11 as Some).0: std::cmp::Ordering);
81+
StorageLive(_13);
82+
_13 = discriminant(_12);
83+
_0 = Le(move _13, const 0_i8);
84+
StorageDead(_13);
85+
StorageDead(_11);
86+
StorageDead(_12);
87+
return;
88+
}
89+
}
+25-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1-
// skip-filecheck
21
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
32

43
#![crate_type = "lib"]
54

65
#[derive(PartialOrd, PartialEq)]
76
pub struct MultiField(char, i16);
87

8+
// Because this isn't derived by the impl, it's not on the `{impl#0}-partial_cmp`,
9+
// and thus we need to call it to see what the inlined generic one produces.
10+
pub fn demo_le(a: &MultiField, b: &MultiField) -> bool {
11+
// CHECK-LABEL: fn demo_le
12+
// CHECK: inlined <MultiField as PartialOrd>::le
13+
// CHECK: inlined{{.+}}is_some_and
14+
// CHECK: inlined <MultiField as PartialOrd>::partial_cmp
15+
16+
// CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char);
17+
// CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char);
18+
// CHECK: Cmp(move [[A0]], move [[B0]]);
19+
20+
// CHECK: [[D0:_[0-9]+]] = discriminant({{.+}});
21+
// CHECK: switchInt(move [[D0]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}];
22+
23+
// CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16);
24+
// CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16);
25+
// CHECK: Cmp(move [[A1]], move [[B1]]);
26+
27+
// CHECK: [[D1:_[0-9]+]] = discriminant({{.+}});
28+
// CHECK: _0 = Le(move [[D1]], const 0_i8);
29+
*a <= *b
30+
}
31+
932
// EMIT_MIR derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir
33+
// EMIT_MIR derived_ord.demo_le.PreCodegen.after.mir

‎tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// MIR for `<impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp` after PreCodegen
1+
// MIR for `<impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp` after PreCodegen
22

3-
fn <impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
3+
fn <impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
44
debug self => _1;
55
debug other => _2;
66
let mut _0: std::option::Option<std::cmp::Ordering>;

‎tests/ui/lifetimes/static-typos.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn stati<T: 'stati>() {}
2+
//~^ ERROR use of undeclared lifetime name `'stati`
3+
4+
fn statoc<T: 'statoc>() {}
5+
//~^ ERROR use of undeclared lifetime name `'statoc`
6+
7+
fn main() {}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0261]: use of undeclared lifetime name `'stati`
2+
--> $DIR/static-typos.rs:1:13
3+
|
4+
LL | fn stati<T: 'stati>() {}
5+
| ^^^^^^ undeclared lifetime
6+
|
7+
help: you may have misspelled the `'static` lifetime
8+
|
9+
LL | fn stati<T: 'static>() {}
10+
| +
11+
12+
error[E0261]: use of undeclared lifetime name `'statoc`
13+
--> $DIR/static-typos.rs:4:14
14+
|
15+
LL | fn statoc<T: 'statoc>() {}
16+
| ^^^^^^^ undeclared lifetime
17+
|
18+
help: you may have misspelled the `'static` lifetime
19+
|
20+
LL - fn statoc<T: 'statoc>() {}
21+
LL + fn statoc<T: 'static>() {}
22+
|
23+
24+
error: aborting due to 2 previous errors
25+
26+
For more information about this error, try `rustc --explain E0261`.

0 commit comments

Comments
 (0)
Please sign in to comment.