about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_abi/src/layout.rs76
-rw-r--r--compiler/rustc_abi/src/lib.rs69
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs9
-rw-r--r--compiler/rustc_resolve/src/late.rs38
-rw-r--r--library/core/src/fmt/mod.rs6
-rw-r--r--library/std/src/sys/unix/fs.rs1
-rw-r--r--src/tools/build_helper/src/ci.rs6
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr84
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.stderr42
-rw-r--r--tests/ui/span/issue-39698.stderr34
11 files changed, 189 insertions, 180 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7f91d12a419..f0a3553da2b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2009,9 +2009,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
 name = "jemalloc-sys"
-version = "0.5.3+5.3.0-patched"
+version = "0.5.4+5.3.0-patched"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9bd5d616ea7ed58b571b2e209a65759664d7fb021a0819d7a790afc67e47ca1"
+checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2"
 dependencies = [
  "cc",
  "libc",
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 0706dc18f0e..e096ad7e6df 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -53,32 +53,32 @@ pub trait LayoutCalculator {
         kind: StructKind,
     ) -> Option<LayoutS> {
         let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
-        // Enums prefer niches close to the beginning or the end of the variants so that other (smaller)
-        // data-carrying variants can be packed into the space after/before the niche.
+        // Enums prefer niches close to the beginning or the end of the variants so that other
+        // (smaller) data-carrying variants can be packed into the space after/before the niche.
         // If the default field ordering does not give us a niche at the front then we do a second
-        // run and bias niches to the right and then check which one is closer to one of the struct's
-        // edges.
+        // run and bias niches to the right and then check which one is closer to one of the
+        // struct's edges.
         if let Some(layout) = &layout {
             // Don't try to calculate an end-biased layout for unsizable structs,
             // otherwise we could end up with different layouts for
-            // Foo<Type> and Foo<dyn Trait> which would break unsizing
+            // Foo<Type> and Foo<dyn Trait> which would break unsizing.
             if !matches!(kind, StructKind::MaybeUnsized) {
                 if let Some(niche) = layout.largest_niche {
                     let head_space = niche.offset.bytes();
-                    let niche_length = niche.value.size(dl).bytes();
-                    let tail_space = layout.size.bytes() - head_space - niche_length;
+                    let niche_len = niche.value.size(dl).bytes();
+                    let tail_space = layout.size.bytes() - head_space - niche_len;
 
-                    // This may end up doing redundant work if the niche is already in the last field
-                    // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
-                    // the unpadded size so we try anyway.
+                    // This may end up doing redundant work if the niche is already in the last
+                    // field (e.g. a trailing bool) and there is tail padding. But it's non-trivial
+                    // to get the unpadded size so we try anyway.
                     if fields.len() > 1 && head_space != 0 && tail_space > 0 {
                         let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End)
                             .expect("alt layout should always work");
-                        let niche = alt_layout
+                        let alt_niche = alt_layout
                             .largest_niche
                             .expect("alt layout should have a niche like the regular one");
-                        let alt_head_space = niche.offset.bytes();
-                        let alt_niche_len = niche.value.size(dl).bytes();
+                        let alt_head_space = alt_niche.offset.bytes();
+                        let alt_niche_len = alt_niche.value.size(dl).bytes();
                         let alt_tail_space =
                             alt_layout.size.bytes() - alt_head_space - alt_niche_len;
 
@@ -93,7 +93,7 @@ pub trait LayoutCalculator {
                             alt_layout: {}\n",
                             layout.size.bytes(),
                             head_space,
-                            niche_length,
+                            niche_len,
                             tail_space,
                             alt_head_space,
                             alt_niche_len,
@@ -684,7 +684,8 @@ pub trait LayoutCalculator {
                 // Also do not overwrite any already existing "clever" ABIs.
                 if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
                     variant.abi = abi;
-                    // Also need to bump up the size and alignment, so that the entire value fits in here.
+                    // Also need to bump up the size and alignment, so that the entire value fits
+                    // in here.
                     variant.size = cmp::max(variant.size, size);
                     variant.align.abi = cmp::max(variant.align.abi, align.abi);
                 }
@@ -868,15 +869,15 @@ fn univariant(
 
         // If `-Z randomize-layout` was enabled for the type definition we can shuffle
         // the field ordering to try and catch some code making assumptions about layouts
-        // we don't guarantee
+        // we don't guarantee.
         if repr.can_randomize_type_layout() && cfg!(feature = "randomize") {
             #[cfg(feature = "randomize")]
             {
-                // `ReprOptions.layout_seed` is a deterministic seed that we can use to
-                // randomize field ordering with
+                // `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
+                // ordering.
                 let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64());
 
-                // Shuffle the ordering of the fields
+                // Shuffle the ordering of the fields.
                 optimizing.shuffle(&mut rng);
             }
             // Otherwise we just leave things alone and actually optimize the type's fields
@@ -892,27 +893,26 @@ fn univariant(
                 .max()
                 .unwrap_or(0);
 
-            // Calculates a sort key to group fields by their alignment or possibly some size-derived
-            // pseudo-alignment.
+            // Calculates a sort key to group fields by their alignment or possibly some
+            // size-derived pseudo-alignment.
             let alignment_group_key = |layout: Layout<'_>| {
                 if let Some(pack) = pack {
-                    // return the packed alignment in bytes
+                    // Return the packed alignment in bytes.
                     layout.align().abi.min(pack).bytes()
                 } else {
-                    // returns log2(effective-align).
-                    // This is ok since `pack` applies to all fields equally.
-                    // The calculation assumes that size is an integer multiple of align, except for ZSTs.
-                    //
+                    // Returns `log2(effective-align)`. This is ok since `pack` applies to all
+                    // fields equally. The calculation assumes that size is an integer multiple of
+                    // align, except for ZSTs.
                     let align = layout.align().abi.bytes();
                     let size = layout.size().bytes();
                     let niche_size = layout.largest_niche().map(|n| n.available(dl)).unwrap_or(0);
-                    // group [u8; 4] with align-4 or [u8; 6] with align-2 fields
+                    // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields.
                     let size_as_align = align.max(size).trailing_zeros();
                     let size_as_align = if largest_niche_size > 0 {
                         match niche_bias {
-                            // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the array
-                            // to the front in the first case (for aligned loads) but keep the bool in front
-                            // in the second case for its niches.
+                            // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the
+                            // array to the front in the first case (for aligned loads) but keep
+                            // the bool in front in the second case for its niches.
                             NicheBias::Start => max_field_align.trailing_zeros().min(size_as_align),
                             // When moving niches towards the end of the struct then for
                             // A((u8, u8, u8, bool), (u8, bool, u8)) we want to keep the first tuple
@@ -931,14 +931,14 @@ fn univariant(
 
             match kind {
                 StructKind::AlwaysSized | StructKind::MaybeUnsized => {
-                    // Currently `LayoutS` only exposes a single niche so sorting is usually sufficient
-                    // to get one niche into the preferred position. If it ever supported multiple niches
-                    // then a more advanced pick-and-pack approach could provide better results.
-                    // But even for the single-niche cache it's not optimal. E.g. for
-                    // A(u32, (bool, u8), u16) it would be possible to move the bool to the front
-                    // but it would require packing the tuple together with the u16 to build a 4-byte
-                    // group so that the u32 can be placed after it without padding. This kind
-                    // of packing can't be achieved by sorting.
+                    // Currently `LayoutS` only exposes a single niche so sorting is usually
+                    // sufficient to get one niche into the preferred position. If it ever
+                    // supported multiple niches then a more advanced pick-and-pack approach could
+                    // provide better results. But even for the single-niche cache it's not
+                    // optimal. E.g. for A(u32, (bool, u8), u16) it would be possible to move the
+                    // bool to the front but it would require packing the tuple together with the
+                    // u16 to build a 4-byte group so that the u32 can be placed after it without
+                    // padding. This kind of packing can't be achieved by sorting.
                     optimizing.sort_by_key(|&x| {
                         let f = fields[x];
                         let field_size = f.size().bytes();
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index b30ff058a30..31566c221cc 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -53,10 +53,11 @@ bitflags! {
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
 pub enum IntegerType {
-    /// Pointer sized integer type, i.e. isize and usize. The field shows signedness, that
-    /// is, `Pointer(true)` is isize.
+    /// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g.
+    /// `Pointer(true)` means `isize`.
     Pointer(bool),
-    /// Fix sized integer type, e.g. i8, u32, i128 The bool field shows signedness, `Fixed(I8, false)` means `u8`
+    /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. The bool field shows signedness, e.g.
+    /// `Fixed(I8, false)` means `u8`.
     Fixed(Integer, bool),
 }
 
@@ -69,7 +70,7 @@ impl IntegerType {
     }
 }
 
-/// Represents the repr options provided by the user,
+/// Represents the repr options provided by the user.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
 pub struct ReprOptions {
@@ -139,7 +140,7 @@ impl ReprOptions {
     }
 
     /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
-    /// was enabled for its declaration crate
+    /// was enabled for its declaration crate.
     pub fn can_randomize_type_layout(&self) -> bool {
         !self.inhibit_struct_field_reordering_opt()
             && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
@@ -217,7 +218,8 @@ pub enum TargetDataLayoutErrors<'a> {
 }
 
 impl TargetDataLayout {
-    /// Parse data layout from an [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
+    /// Parse data layout from an
+    /// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
     ///
     /// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be
     /// determined from llvm string.
@@ -242,10 +244,11 @@ impl TargetDataLayout {
         };
 
         // Parse a size string.
-        let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
+        let parse_size =
+            |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
 
         // Parse an alignment string.
-        let align = |s: &[&'a str], cause: &'a str| {
+        let parse_align = |s: &[&'a str], cause: &'a str| {
             if s.is_empty() {
                 return Err(TargetDataLayoutErrors::MissingAlignment { cause });
             }
@@ -269,22 +272,22 @@ impl TargetDataLayout {
                 [p] if p.starts_with('P') => {
                     dl.instruction_address_space = parse_address_space(&p[1..], "P")?
                 }
-                ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
-                ["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
-                ["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
+                ["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
+                ["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
+                ["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
                 // FIXME(erikdesjardins): we should be parsing nonzero address spaces
                 // this will require replacing TargetDataLayout::{pointer_size,pointer_align}
                 // with e.g. `fn pointer_size_in(AddressSpace)`
                 [p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
-                    dl.pointer_size = size(s, p)?;
-                    dl.pointer_align = align(a, p)?;
+                    dl.pointer_size = parse_size(s, p)?;
+                    dl.pointer_align = parse_align(a, p)?;
                 }
                 [s, ref a @ ..] if s.starts_with('i') => {
                     let Ok(bits) = s[1..].parse::<u64>() else {
-                        size(&s[1..], "i")?; // For the user error.
+                        parse_size(&s[1..], "i")?; // For the user error.
                         continue;
                     };
-                    let a = align(a, s)?;
+                    let a = parse_align(a, s)?;
                     match bits {
                         1 => dl.i1_align = a,
                         8 => dl.i8_align = a,
@@ -301,8 +304,8 @@ impl TargetDataLayout {
                     }
                 }
                 [s, ref a @ ..] if s.starts_with('v') => {
-                    let v_size = size(&s[1..], "v")?;
-                    let a = align(a, s)?;
+                    let v_size = parse_size(&s[1..], "v")?;
+                    let a = parse_align(a, s)?;
                     if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
                         v.1 = a;
                         continue;
@@ -747,7 +750,6 @@ impl Align {
 /// A pair of alignments, ABI-mandated and preferred.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-
 pub struct AbiAndPrefAlign {
     pub abi: Align,
     pub pref: Align,
@@ -773,7 +775,6 @@ impl AbiAndPrefAlign {
 /// Integers, also used for enum discriminants.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
-
 pub enum Integer {
     I8,
     I16,
@@ -937,8 +938,7 @@ impl Primitive {
 }
 
 /// Inclusive wrap-around range of valid values, that is, if
-/// start > end, it represents `start..=MAX`,
-/// followed by `0..=end`.
+/// start > end, it represents `start..=MAX`, followed by `0..=end`.
 ///
 /// That is, for an i8 primitive, a range of `254..=2` means following
 /// sequence:
@@ -970,21 +970,21 @@ impl WrappingRange {
 
     /// Returns `self` with replaced `start`
     #[inline(always)]
-    pub fn with_start(mut self, start: u128) -> Self {
+    fn with_start(mut self, start: u128) -> Self {
         self.start = start;
         self
     }
 
     /// Returns `self` with replaced `end`
     #[inline(always)]
-    pub fn with_end(mut self, end: u128) -> Self {
+    fn with_end(mut self, end: u128) -> Self {
         self.end = end;
         self
     }
 
     /// Returns `true` if `size` completely fills the range.
     #[inline]
-    pub fn is_full_for(&self, size: Size) -> bool {
+    fn is_full_for(&self, size: Size) -> bool {
         let max_value = size.unsigned_int_max();
         debug_assert!(self.start <= max_value && self.end <= max_value);
         self.start == (self.end.wrapping_add(1) & max_value)
@@ -1066,7 +1066,8 @@ impl Scalar {
     }
 
     #[inline]
-    /// Allows the caller to mutate the valid range. This operation will panic if attempted on a union.
+    /// Allows the caller to mutate the valid range. This operation will panic if attempted on a
+    /// union.
     pub fn valid_range_mut(&mut self) -> &mut WrappingRange {
         match self {
             Scalar::Initialized { valid_range, .. } => valid_range,
@@ -1074,7 +1075,8 @@ impl Scalar {
         }
     }
 
-    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole layout
+    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole
+    /// layout.
     #[inline]
     pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
         match *self {
@@ -1252,7 +1254,6 @@ impl AddressSpace {
 /// in terms of categories of C types there are ABI rules for.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-
 pub enum Abi {
     Uninhabited,
     Scalar(Scalar),
@@ -1457,17 +1458,19 @@ impl Niche {
             return None;
         }
 
-        // Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound.
-        // Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy the niche of zero.
-        // This is accomplished by preferring enums with 2 variants(`count==1`) and always taking the shortest path to niche zero.
-        // Having `None` in niche zero can enable some special optimizations.
+        // Extend the range of valid values being reserved by moving either `v.start` or `v.end`
+        // bound. Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy
+        // the niche of zero. This is accomplished by preferring enums with 2 variants(`count==1`)
+        // and always taking the shortest path to niche zero. Having `None` in niche zero can
+        // enable some special optimizations.
         //
         // Bound selection criteria:
         // 1. Select closest to zero given wrapping semantics.
         // 2. Avoid moving past zero if possible.
         //
-        // In practice this means that enums with `count > 1` are unlikely to claim niche zero, since they have to fit perfectly.
-        // If niche zero is already reserved, the selection of bounds are of little interest.
+        // In practice this means that enums with `count > 1` are unlikely to claim niche zero,
+        // since they have to fit perfectly. If niche zero is already reserved, the selection of
+        // bounds are of little interest.
         let move_start = |v: WrappingRange| {
             let start = v.start.wrapping_sub(count) & max_value;
             Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) }))
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 0b0a708e42b..0a425be52ff 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -617,12 +617,17 @@ impl<'tcx> Instance<'tcx> {
         v: EarlyBinder<T>,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<TyCtxt<'tcx>> + Clone,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         if let Some(args) = self.args_for_mir_body() {
             tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
-            tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
+            // We're using `instantiate_identity` as e.g.
+            // `FnPtrShim` is separately generated for every
+            // instantiation of the `FnDef`, so the MIR body
+            // is already instantiated. Any generic parameters it
+            // contains are generic parameters from the caller.
+            tcx.try_normalize_erasing_regions(param_env, v.instantiate_identity())
         }
     }
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 15ec727e4c9..ece8b7f6ec9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -41,9 +41,6 @@ type Res = def::Res<NodeId>;
 
 type IdentMap<T> = FxHashMap<Ident, T>;
 
-/// Map from the name in a pattern to its binding mode.
-type BindingMap = IdentMap<BindingInfo>;
-
 use diagnostics::{
     ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime, MissingLifetimeKind,
 };
@@ -3164,8 +3161,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     /// this is done hygienically. This could arise for a macro
     /// that expands into an or-pattern where one 'x' was from the
     /// user and one 'x' came from the macro.
-    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
-        let mut binding_map = FxHashMap::default();
+    fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
+        let mut binding_map = FxIndexMap::default();
 
         pat.walk(&mut |pat| {
             match pat.kind {
@@ -3200,22 +3197,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
     /// Checks that all of the arms in an or-pattern have exactly the
     /// same set of bindings, with the same binding modes for each.
-    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
-        let mut missing_vars = FxHashMap::default();
-        let mut inconsistent_vars = FxHashMap::default();
+    fn check_consistent_bindings(
+        &mut self,
+        pats: &[P<Pat>],
+    ) -> Vec<FxIndexMap<Ident, BindingInfo>> {
+        // pats is consistent.
+        let mut missing_vars = FxIndexMap::default();
+        let mut inconsistent_vars = FxIndexMap::default();
 
         // 1) Compute the binding maps of all arms.
         let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::<Vec<_>>();
 
         // 2) Record any missing bindings or binding mode inconsistencies.
-        for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) {
+        for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) {
             // Check against all arms except for the same pattern which is always self-consistent.
-            let inners = pats
+            let inners = maps
                 .iter()
-                .enumerate()
+                .zip(pats.iter())
                 .filter(|(_, pat)| pat.id != pat_outer.id)
-                .flat_map(|(idx, _)| maps[idx].iter())
-                .map(|(key, binding)| (key.name, map_outer.get(&key), binding));
+                .flat_map(|(map, _)| map)
+                .map(|(key, binding)| (key.name, map_outer.get(key), binding));
+
+            let inners = inners.collect::<Vec<_>>();
 
             for (name, info, &binding_inner) in inners {
                 match info {
@@ -3244,10 +3247,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
 
         // 3) Report all missing variables we found.
-        let mut missing_vars = missing_vars.into_iter().collect::<Vec<_>>();
-        missing_vars.sort_by_key(|&(sym, ref _err)| sym);
-
-        for (name, mut v) in missing_vars.into_iter() {
+        for (name, mut v) in missing_vars {
             if inconsistent_vars.contains_key(&name) {
                 v.could_be_path = false;
             }
@@ -3258,10 +3258,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
 
         // 4) Report all inconsistencies in binding modes we found.
-        let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
-        inconsistent_vars.sort();
         for (name, v) in inconsistent_vars {
-            self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
+            self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
         }
 
         // 5) Finally bubble up all the binding maps.
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index fc91d1afc43..f7d3cda2fe9 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -791,8 +791,10 @@ pub trait Octal {
 /// assert_eq!(format!("l as binary is: {l:b}"), "l as binary is: 1101011");
 ///
 /// assert_eq!(
-///     format!("l as binary is: {l:#032b}"),
-///     "l as binary is: 0b000000000000000000000001101011"
+///     // Note that the `0b` prefix added by `#` is included in the total width, so we
+///     // need to add two to correctly display all 32 bits.
+///     format!("l as binary is: {l:#034b}"),
+///     "l as binary is: 0b00000000000000000000000001101011"
 /// );
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 764e1f25790..5ed2bdd7fe3 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1391,6 +1391,7 @@ impl FromInner<FileDesc> for File {
 }
 
 impl AsFd for File {
+    #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
         self.0.as_fd()
     }
diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs
index a8505ec9596..09489b0d9b7 100644
--- a/src/tools/build_helper/src/ci.rs
+++ b/src/tools/build_helper/src/ci.rs
@@ -82,15 +82,15 @@ pub mod gha {
 
     fn start_group(name: impl std::fmt::Display) {
         if is_in_gha() {
-            eprintln!("::group::{name}");
+            println!("::group::{name}");
         } else {
-            eprintln!("{name}")
+            println!("{name}")
         }
     }
 
     fn end_group() {
         if is_in_gha() {
-            eprintln!("::endgroup::");
+            println!("::endgroup::");
         }
     }
 
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 4457b7893d5..7f182a85787 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -103,22 +103,6 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 |
    |                 variable not in all patterns
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
-   |
-LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |                        -        ^^^^ pattern doesn't bind `c`
-   |                        |
-   |                        variable not in all patterns
-
-error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
-   |
-LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |                            -    ^^^^ pattern doesn't bind `d`
-   |                            |
-   |                            variable not in all patterns
-
 error[E0408]: variable `e` is not bound in all patterns
   --> $DIR/missing-bindings.rs:45:10
    |
@@ -143,6 +127,22 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 |
    |                 variable not in all patterns
 
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:45:33
+   |
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                        -        ^^^^ pattern doesn't bind `c`
+   |                        |
+   |                        variable not in all patterns
+
+error[E0408]: variable `d` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:45:33
+   |
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                            -    ^^^^ pattern doesn't bind `d`
+   |                            |
+   |                            variable not in all patterns
+
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:61:29
    |
@@ -151,14 +151,6 @@ LL |                     Ok(a) | Err(_),
    |                        |
    |                        variable not in all patterns
 
-error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:69:21
-   |
-LL |                     A(_, a) |
-   |                          - variable not in all patterns
-LL |                     B(b),
-   |                     ^^^^ pattern doesn't bind `a`
-
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/missing-bindings.rs:68:21
    |
@@ -168,6 +160,14 @@ LL |                     B(b),
    |                       - variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:69:21
+   |
+LL |                     A(_, a) |
+   |                          - variable not in all patterns
+LL |                     B(b),
+   |                     ^^^^ pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:72:17
    |
 LL |                     A(_, a) |
@@ -185,6 +185,24 @@ LL |                     B(b),
 LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `b`
 
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:57:13
+   |
+LL | /             V1(
+LL | |
+LL | |
+LL | |                 A(
+...  |
+LL | |                 B(Ok(a) | Err(a))
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `b`
+...
+LL |                       B(b),
+   |                         - variable not in all patterns
+...
+LL |               V3(c),
+   |               ^^^^^ pattern doesn't bind `b`
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/missing-bindings.rs:57:13
    |
@@ -219,24 +237,6 @@ LL |                     A(_, a) |
 LL |             V3(c),
    |             ^^^^^ pattern doesn't bind `a`
 
-error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:57:13
-   |
-LL | /             V1(
-LL | |
-LL | |
-LL | |                 A(
-...  |
-LL | |                 B(Ok(a) | Err(a))
-LL | |             ) |
-   | |_____________^ pattern doesn't bind `b`
-...
-LL |                       B(b),
-   |                         - variable not in all patterns
-...
-LL |               V3(c),
-   |               ^^^^^ pattern doesn't bind `b`
-
 error: aborting due to 26 previous errors
 
 For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr
index 42b7281d7b0..d6240fb8f87 100644
--- a/tests/ui/resolve/resolve-inconsistent-names.stderr
+++ b/tests/ui/resolve/resolve-inconsistent-names.stderr
@@ -1,11 +1,3 @@
-error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:13:12
-   |
-LL |        a | b => {}
-   |        -   ^ pattern doesn't bind `a`
-   |        |
-   |        variable not in all patterns
-
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:13:8
    |
@@ -14,6 +6,14 @@ LL |        a | b => {}
    |        |
    |        pattern doesn't bind `b`
 
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/resolve-inconsistent-names.rs:13:12
+   |
+LL |        a | b => {}
+   |        -   ^ pattern doesn't bind `a`
+   |        |
+   |        variable not in all patterns
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:19:9
    |
@@ -54,6 +54,19 @@ LL |         (A, B) | (ref B, c) | (c, A) => ()
    |             |
    |             first binding
 
+error[E0408]: variable `Const2` is not bound in all patterns
+  --> $DIR/resolve-inconsistent-names.rs:31:9
+   |
+LL |         (CONST1, _) | (_, Const2) => ()
+   |         ^^^^^^^^^^^       ------ variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Const2`
+   |
+help: if you meant to match on constant `m::Const2`, use the full path in the pattern
+   |
+LL |         (CONST1, _) | (_, m::Const2) => ()
+   |                           ~~~~~~~~~
+
 error[E0408]: variable `CONST1` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:31:23
    |
@@ -68,19 +81,6 @@ note: you might have meant to match on constant `m::CONST1`, which exists but is
 LL |     const CONST1: usize = 10;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible
 
-error[E0408]: variable `Const2` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:31:9
-   |
-LL |         (CONST1, _) | (_, Const2) => ()
-   |         ^^^^^^^^^^^       ------ variable not in all patterns
-   |         |
-   |         pattern doesn't bind `Const2`
-   |
-help: if you meant to match on constant `m::Const2`, use the full path in the pattern
-   |
-LL |         (CONST1, _) | (_, m::Const2) => ()
-   |                           ~~~~~~~~~
-
 error[E0308]: mismatched types
   --> $DIR/resolve-inconsistent-names.rs:19:19
    |
diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr
index 81211b20a01..50008083211 100644
--- a/tests/ui/span/issue-39698.stderr
+++ b/tests/ui/span/issue-39698.stderr
@@ -1,3 +1,13 @@
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/issue-39698.rs:10:9
+   |
+LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |         ^^^^^^^^^^^            -    ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `b`
+   |         |                      |    |
+   |         |                      |    pattern doesn't bind `b`
+   |         |                      variable not in all patterns
+   |         pattern doesn't bind `b`
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:9
    |
@@ -8,16 +18,6 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
 
-error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/issue-39698.rs:10:37
-   |
-LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
-   |                  -          -       ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `d`
-   |                  |          |       |
-   |                  |          |       pattern doesn't bind `d`
-   |                  |          variable not in all patterns
-   |                  variable not in all patterns
-
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:23
    |
@@ -28,15 +28,15 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |               |       pattern doesn't bind `a`
    |               variable not in all patterns
 
-error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/issue-39698.rs:10:9
+error[E0408]: variable `d` is not bound in all patterns
+  --> $DIR/issue-39698.rs:10:37
    |
 LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
-   |         ^^^^^^^^^^^            -    ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `b`
-   |         |                      |    |
-   |         |                      |    pattern doesn't bind `b`
-   |         |                      variable not in all patterns
-   |         pattern doesn't bind `b`
+   |                  -          -       ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `d`
+   |                  |          |       |
+   |                  |          |       pattern doesn't bind `d`
+   |                  |          variable not in all patterns
+   |                  variable not in all patterns
 
 error: aborting due to 4 previous errors