about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-15 11:40:17 +0000
committerbors <bors@rust-lang.org>2025-03-15 11:40:17 +0000
commit4d30011f6c616be074ba655a75e5d55441232bbb (patch)
tree8c4907dddd7f6ec926f92e44247ba3f9534b8b4c
parentaa95b9648ad0383a3fd73b5271dd86f848b7c00c (diff)
parent35aa49dead043e3ea9312f23c651f3360f954406 (diff)
downloadrust-4d30011f6c616be074ba655a75e5d55441232bbb.tar.gz
rust-4d30011f6c616be074ba655a75e5d55441232bbb.zip
Auto merge of #138532 - matthiaskrgr:rollup-mgcynqu, r=matthiaskrgr
Rollup of 5 pull requests

Successful merges:

 - #138283 (Enforce type of const param correctly in MIR typeck)
 - #138439 (feat: check ARG_MAX on Unix platforms)
 - #138502 (resolve: Avoid some unstable iteration)
 - #138514 (Remove fake borrows of refs that are converted into non-refs in `MakeByMoveBody`)
 - #138524 (Mark myself as unavailable for reviews temporarily)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs16
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/back/command.rs47
-rw-r--r--compiler/rustc_data_structures/src/unord.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs41
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs1
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs15
-rw-r--r--compiler/rustc_resolve/src/ident.rs1
-rw-r--r--compiler/rustc_resolve/src/late.rs24
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs12
-rw-r--r--compiler/rustc_resolve/src/lib.rs24
-rw-r--r--compiler/rustc_resolve/src/macros.rs6
-rw-r--r--tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir81
-rw-r--r--tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir64
-rw-r--r--tests/mir-opt/async_closure_fake_read_for_by_move.rs18
-rw-r--r--tests/ui/const-generics/adt_const_params/check-type-in-mir.rs16
-rw-r--r--tests/ui/const-generics/adt_const_params/check-type-in-mir.stderr14
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs12
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr27
-rw-r--r--triagebot.toml1
21 files changed, 394 insertions, 49 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 94a5538ea3f..0fda3e31690 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1771,6 +1771,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 {
                     span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
                 }
+            } else if let Const::Ty(_, ct) = constant.const_
+                && let ty::ConstKind::Param(p) = ct.kind()
+            {
+                let body_def_id = self.universal_regions.defining_ty.def_id();
+                let const_param = tcx.generics_of(body_def_id).const_param(p, tcx);
+                self.ascribe_user_type(
+                    constant.const_.ty(),
+                    ty::UserType::new(ty::UserTypeKind::TypeOf(
+                        const_param.def_id,
+                        UserArgs {
+                            args: self.universal_regions.defining_ty.args(),
+                            user_self_ty: None,
+                        },
+                    )),
+                    locations.span(self.body),
+                );
             }
 
             if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index f8e086b2bb7..8f6b405fcef 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -183,6 +183,20 @@ impl<'tcx> DefiningTy<'tcx> {
             | DefiningTy::GlobalAsm(def_id) => def_id,
         }
     }
+
+    /// Returns the args of the `DefiningTy`. These are equivalent to the identity
+    /// substs of the body, but replaced with region vids.
+    pub(crate) fn args(&self) -> ty::GenericArgsRef<'tcx> {
+        match *self {
+            DefiningTy::Closure(_, args)
+            | DefiningTy::Coroutine(_, args)
+            | DefiningTy::CoroutineClosure(_, args)
+            | DefiningTy::FnDef(_, args)
+            | DefiningTy::Const(_, args)
+            | DefiningTy::InlineConst(_, args) => args,
+            DefiningTy::GlobalAsm(_) => ty::List::empty(),
+        }
+    }
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs
index 383d0579e52..05351bd6ca3 100644
--- a/compiler/rustc_codegen_ssa/src/back/command.rs
+++ b/compiler/rustc_codegen_ssa/src/back/command.rs
@@ -137,12 +137,42 @@ impl Command {
     /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
     /// or `false` if we should attempt to spawn and see what the OS says.
     pub(crate) fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
-        // We mostly only care about Windows in this method, on Unix the limits
-        // can be gargantuan anyway so we're pretty unlikely to hit them
-        if cfg!(unix) {
+        #[cfg(not(any(windows, unix)))]
+        {
             return false;
         }
 
+        // On Unix the limits can be gargantuan anyway so we're pretty
+        // unlikely to hit them, but might still exceed it.
+        // We consult ARG_MAX here to get an estimate.
+        #[cfg(unix)]
+        {
+            let ptr_size = mem::size_of::<usize>();
+            // arg + \0 + pointer
+            let args_size = self.args.iter().fold(0usize, |acc, a| {
+                let arg = a.as_encoded_bytes().len();
+                let nul = 1;
+                acc.saturating_add(arg).saturating_add(nul).saturating_add(ptr_size)
+            });
+            // key + `=` + value + \0 + pointer
+            let envs_size = self.env.iter().fold(0usize, |acc, (k, v)| {
+                let k = k.as_encoded_bytes().len();
+                let eq = 1;
+                let v = v.as_encoded_bytes().len();
+                let nul = 1;
+                acc.saturating_add(k)
+                    .saturating_add(eq)
+                    .saturating_add(v)
+                    .saturating_add(nul)
+                    .saturating_add(ptr_size)
+            });
+            let arg_max = match unsafe { libc::sysconf(libc::_SC_ARG_MAX) } {
+                -1 => return false, // Go to OS anyway.
+                max => max as usize,
+            };
+            return args_size.saturating_add(envs_size) > arg_max;
+        }
+
         // Ok so on Windows to spawn a process is 32,768 characters in its
         // command line [1]. Unfortunately we don't actually have access to that
         // as it's calculated just before spawning. Instead we perform a
@@ -165,9 +195,14 @@ impl Command {
         //
         // [1]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
         // [2]: https://devblogs.microsoft.com/oldnewthing/?p=41553
-
-        let estimated_command_line_len = self.args.iter().map(|a| a.len()).sum::<usize>();
-        estimated_command_line_len > 1024 * 6
+        #[cfg(windows)]
+        {
+            let estimated_command_line_len = self
+                .args
+                .iter()
+                .fold(0usize, |acc, a| acc.saturating_add(a.as_encoded_bytes().len()));
+            return estimated_command_line_len > 1024 * 6;
+        }
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs
index 14c3162165c..baa66cd7c85 100644
--- a/compiler/rustc_data_structures/src/unord.rs
+++ b/compiler/rustc_data_structures/src/unord.rs
@@ -259,6 +259,12 @@ impl<V: Eq + Hash> UnordSet<V> {
         self.inner.is_empty()
     }
 
+    /// If the set has only one element, returns it, otherwise returns `None`.
+    #[inline]
+    pub fn get_only(&self) -> Option<&V> {
+        if self.inner.len() == 1 { self.inner.iter().next() } else { None }
+    }
+
     #[inline]
     pub fn insert(&mut self, v: V) -> bool {
         self.inner.insert(v)
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 29949f8b3e3..a508487c796 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -33,6 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
+use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{Diag, ErrorGuaranteed};
 use rustc_hir::LangItem;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
@@ -169,7 +170,7 @@ pub struct ResolverGlobalCtxt {
     /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
     pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
     pub effective_visibilities: EffectiveVisibilities,
-    pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
+    pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
     pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
     pub module_children: LocalDefIdMap<Vec<ModChild>>,
     pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 9cd7045a0a2..89a306c6104 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -178,7 +178,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
                 ),
             };
 
-            (
+            Some((
                 FieldIdx::from_usize(child_field_idx + num_args),
                 (
                     FieldIdx::from_usize(parent_field_idx + num_args),
@@ -186,9 +186,10 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
                     peel_deref,
                     child_precise_captures,
                 ),
-            )
+            ))
         },
     )
+    .flatten()
     .collect();
 
     if coroutine_kind == ty::ClosureKind::FnOnce {
@@ -312,10 +313,46 @@ impl<'tcx> MutVisitor<'tcx> for MakeByMoveBody<'tcx> {
         self.super_place(place, context, location);
     }
 
+    fn visit_statement(&mut self, statement: &mut mir::Statement<'tcx>, location: mir::Location) {
+        // Remove fake borrows of closure captures if that capture has been
+        // replaced with a by-move version of that capture.
+        //
+        // For example, imagine we capture `Foo` in the parent and `&Foo`
+        // in the child. We will emit two fake borrows like:
+        //
+        // ```
+        //    _2 = &fake shallow (*(_1.0: &Foo));
+        //    _3 = &fake shallow (_1.0: &Foo);
+        // ```
+        //
+        // However, since this transform is responsible for replacing
+        // `_1.0: &Foo` with `_1.0: Foo`, that makes the second fake borrow
+        // obsolete, and we should replace it with a nop.
+        //
+        // As a side-note, we don't actually even care about fake borrows
+        // here at all since they're fully a MIR borrowck artifact, and we
+        // don't need to borrowck by-move MIR bodies. But it's best to preserve
+        // as much as we can between these two bodies :)
+        if let mir::StatementKind::Assign(box (_, rvalue)) = &statement.kind
+            && let mir::Rvalue::Ref(_, mir::BorrowKind::Fake(mir::FakeBorrowKind::Shallow), place) =
+                rvalue
+            && let mir::PlaceRef {
+                local: ty::CAPTURE_STRUCT_LOCAL,
+                projection: [mir::ProjectionElem::Field(idx, _)],
+            } = place.as_ref()
+            && let Some(&(_, _, true, _)) = self.field_remapping.get(&idx)
+        {
+            statement.kind = mir::StatementKind::Nop;
+        }
+
+        self.super_statement(statement, location);
+    }
+
     fn visit_local_decl(&mut self, local: mir::Local, local_decl: &mut mir::LocalDecl<'tcx>) {
         // Replace the type of the self arg.
         if local == ty::CAPTURE_STRUCT_LOCAL {
             local_decl.ty = self.by_move_coroutine_ty;
         }
+        self.super_local_decl(local, local_decl);
     }
 }
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 42fe01b1c84..763e9207a12 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1115,6 +1115,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
                 }
             });
         } else {
+            #[allow(rustc::potential_query_instability)] // FIXME
             for ident in single_imports.iter().cloned() {
                 let result = self.r.maybe_resolve_ident_in_module(
                     ModuleOrUniformRoot::Module(module),
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 41f4254eede..5361af98f3c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -6,6 +6,7 @@ use rustc_ast::{
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, MultiSpan, SuggestionStyle,
@@ -1467,6 +1468,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             return;
         }
 
+        #[allow(rustc::potential_query_instability)] // FIXME
         let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident))| {
             if unused_ident.name == ident.name { Some((def_id, unused_ident)) } else { None }
         });
@@ -2863,18 +2865,11 @@ fn show_candidates(
             } else {
                 // Get the unique item kinds and if there's only one, we use the right kind name
                 // instead of the more generic "items".
-                let mut kinds = accessible_path_strings
+                let kinds = accessible_path_strings
                     .iter()
                     .map(|(_, descr, _, _, _)| *descr)
-                    .collect::<FxHashSet<&str>>()
-                    .into_iter();
-                let kind = if let Some(kind) = kinds.next()
-                    && let None = kinds.next()
-                {
-                    kind
-                } else {
-                    "item"
-                };
+                    .collect::<UnordSet<&str>>();
+                let kind = if let Some(kind) = kinds.get_only() { kind } else { "item" };
                 let s = if kind.ends_with('s') { "es" } else { "s" };
 
                 ("one of these", kind, s, String::new(), "")
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 5f0a2a597e9..27d63198836 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -946,6 +946,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
 
         // Check if one of single imports can still define the name,
         // if it can then our result is not determined and can be invalidated.
+        #[allow(rustc::potential_query_instability)] // FIXME
         for single_import in &resolution.single_imports {
             if ignore_import == Some(*single_import) {
                 // This branch handles a cycle in single imports.
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f3f6c551580..6056a69ee71 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -18,6 +18,7 @@ use rustc_ast::visit::{
 };
 use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
@@ -47,8 +48,6 @@ mod diagnostics;
 
 type Res = def::Res<NodeId>;
 
-type IdentMap<T> = FxHashMap<Ident, T>;
-
 use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime};
 
 #[derive(Copy, Clone, Debug)]
@@ -273,8 +272,8 @@ impl RibKind<'_> {
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
 pub(crate) struct Rib<'ra, R = Res> {
-    pub bindings: IdentMap<R>,
-    pub patterns_with_skipped_bindings: FxHashMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,
+    pub bindings: FxHashMap<Ident, R>,
+    pub patterns_with_skipped_bindings: UnordMap<DefId, Vec<(Span, Result<(), ErrorGuaranteed>)>>,
     pub kind: RibKind<'ra>,
 }
 
@@ -1605,12 +1604,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         // for better diagnostics.
         let mut forward_ty_ban_rib_const_param_ty = Rib {
             bindings: forward_ty_ban_rib.bindings.clone(),
-            patterns_with_skipped_bindings: FxHashMap::default(),
+            patterns_with_skipped_bindings: Default::default(),
             kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
         };
         let mut forward_const_ban_rib_const_param_ty = Rib {
             bindings: forward_const_ban_rib.bindings.clone(),
-            patterns_with_skipped_bindings: FxHashMap::default(),
+            patterns_with_skipped_bindings: Default::default(),
             kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
         };
         // We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
@@ -2334,7 +2333,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             let local_candidates = self.lifetime_elision_candidates.take();
 
             if let Some(candidates) = local_candidates {
-                let distinct: FxHashSet<_> = candidates.iter().map(|(res, _)| *res).collect();
+                let distinct: UnordSet<_> = candidates.iter().map(|(res, _)| *res).collect();
                 let lifetime_count = distinct.len();
                 if lifetime_count != 0 {
                     parameter_info.push(ElisionFnParameter {
@@ -2358,14 +2357,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         }
                     }));
                 }
-                let mut distinct_iter = distinct.into_iter();
-                if let Some(res) = distinct_iter.next() {
+                if !distinct.is_empty() {
                     match elision_lifetime {
                         // We are the first parameter to bind lifetimes.
                         Elision::None => {
-                            if distinct_iter.next().is_none() {
+                            if let Some(res) = distinct.get_only() {
                                 // We have a single lifetime => success.
-                                elision_lifetime = Elision::Param(res)
+                                elision_lifetime = Elision::Param(*res)
                             } else {
                                 // We have multiple lifetimes => error.
                                 elision_lifetime = Elision::Err;
@@ -2890,6 +2888,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         break;
                     }
 
+                    #[allow(rustc::potential_query_instability)] // FIXME
                     seen_bindings
                         .extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
                 }
@@ -4004,7 +4003,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         }
     }
 
-    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut IdentMap<Res> {
+    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap<Ident, Res> {
         &mut self.ribs[ns].last_mut().unwrap().bindings
     }
 
@@ -5202,6 +5201,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
         late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID));
         visit::walk_crate(&mut late_resolution_visitor, krate);
+        #[allow(rustc::potential_query_instability)] // FIXME
         for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() {
             self.lint_buffer.buffer_lint(
                 lint::builtin::UNUSED_LABELS,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 84858cfc1b1..bcfcc8000c7 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -830,6 +830,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         if let Some(rib) = &self.last_block_rib
             && let RibKind::Normal = rib.kind
         {
+            #[allow(rustc::potential_query_instability)] // FIXME
             for (ident, &res) in &rib.bindings {
                 if let Res::Local(_) = res
                     && path.len() == 1
@@ -1018,6 +1019,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         if let Some(err_code) = err.code {
             if err_code == E0425 {
                 for label_rib in &self.label_ribs {
+                    #[allow(rustc::potential_query_instability)] // FIXME
                     for (label_ident, node_id) in &label_rib.bindings {
                         let ident = path.last().unwrap().ident;
                         if format!("'{ident}") == label_ident.to_string() {
@@ -1177,7 +1179,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let [segment] = path else { return };
         let None = following_seg else { return };
         for rib in self.ribs[ValueNS].iter().rev() {
-            for (def_id, spans) in &rib.patterns_with_skipped_bindings {
+            let patterns_with_skipped_bindings = self.r.tcx.with_stable_hashing_context(|hcx| {
+                rib.patterns_with_skipped_bindings.to_sorted(&hcx, true)
+            });
+            for (def_id, spans) in patterns_with_skipped_bindings {
                 if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id)
                     && let Some(fields) = self.r.field_idents(*def_id)
                 {
@@ -2052,7 +2057,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         if self
             .r
             .extern_crate_map
-            .iter()
+            .items()
             // FIXME: This doesn't include impls like `impl Default for String`.
             .flat_map(|(_, crate_)| self.r.tcx.implementations_of_trait((*crate_, default_trait)))
             .filter_map(|(_, simplified_self_ty)| *simplified_self_ty)
@@ -2261,6 +2266,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 };
 
                 // Locals and type parameters
+                #[allow(rustc::potential_query_instability)] // FIXME
                 for (ident, &res) in &rib.bindings {
                     if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
                         names.push(TypoSuggestion::typo_from_ident(*ident, res));
@@ -2788,6 +2794,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let within_scope = self.is_label_valid_from_rib(rib_index);
 
         let rib = &self.label_ribs[rib_index];
+        #[allow(rustc::potential_query_instability)] // FIXME
         let names = rib
             .bindings
             .iter()
@@ -2799,6 +2806,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             // Upon finding a similar name, get the ident that it was from - the span
             // contained within helps make a useful diagnostic. In addition, determine
             // whether this candidate is within scope.
+            #[allow(rustc::potential_query_instability)] // FIXME
             let (ident, _) = rib.bindings.iter().find(|(ident, _)| ident.name == symbol).unwrap();
             (*ident, within_scope)
         })
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 495ce843fcd..447d5283e27 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -9,7 +9,6 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
-#![allow(rustc::potential_query_instability)]
 #![allow(rustc::untranslatable_diagnostic)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
@@ -47,6 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::FreezeReadGuard;
+use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed};
 use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
 use rustc_feature::BUILTIN_ATTRIBUTES;
@@ -1046,7 +1046,7 @@ pub struct Resolver<'ra, 'tcx> {
     graph_root: Module<'ra>,
 
     prelude: Option<Module<'ra>>,
-    extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'ra>>,
+    extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'ra>>,
 
     /// N.B., this is used only for better diagnostics, not name resolution itself.
     field_names: LocalDefIdMap<Vec<Ident>>,
@@ -1079,7 +1079,7 @@ pub struct Resolver<'ra, 'tcx> {
     extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
 
     /// `CrateNum` resolutions of `extern crate` items.
-    extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
+    extern_crate_map: UnordMap<LocalDefId, CrateNum>,
     module_children: LocalDefIdMap<Vec<ModChild>>,
     trait_map: NodeMap<Vec<TraitCandidate>>,
 
@@ -1102,7 +1102,7 @@ pub struct Resolver<'ra, 'tcx> {
     /// some AST passes can generate identifiers that only resolve to local or
     /// lang items.
     empty_module: Module<'ra>,
-    module_map: FxHashMap<DefId, Module<'ra>>,
+    module_map: FxIndexMap<DefId, Module<'ra>>,
     binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
 
     underscore_disambiguator: u32,
@@ -1136,7 +1136,7 @@ pub struct Resolver<'ra, 'tcx> {
     macro_names: FxHashSet<Ident>,
     builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
     registered_tools: &'tcx RegisteredTools,
-    macro_use_prelude: FxHashMap<Symbol, NameBinding<'ra>>,
+    macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
     macro_map: FxHashMap<DefId, MacroData>,
     dummy_ext_bang: Arc<SyntaxExtension>,
     dummy_ext_derive: Arc<SyntaxExtension>,
@@ -1145,7 +1145,7 @@ pub struct Resolver<'ra, 'tcx> {
     ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
     unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
     /// A map from the macro to all its potentially unused arms.
-    unused_macro_rules: FxIndexMap<LocalDefId, FxHashMap<usize, (Ident, Span)>>,
+    unused_macro_rules: FxIndexMap<LocalDefId, UnordMap<usize, (Ident, Span)>>,
     proc_macro_stubs: FxHashSet<LocalDefId>,
     /// Traces collected during macro resolution and validated when it's complete.
     single_segment_macro_resolutions:
@@ -1259,7 +1259,7 @@ impl<'ra> ResolverArenas<'ra> {
         expn_id: ExpnId,
         span: Span,
         no_implicit_prelude: bool,
-        module_map: &mut FxHashMap<DefId, Module<'ra>>,
+        module_map: &mut FxIndexMap<DefId, Module<'ra>>,
         module_self_bindings: &mut FxHashMap<Module<'ra>, NameBinding<'ra>>,
     ) -> Module<'ra> {
         let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
@@ -1404,7 +1404,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         arenas: &'ra ResolverArenas<'ra>,
     ) -> Resolver<'ra, 'tcx> {
         let root_def_id = CRATE_DEF_ID.to_def_id();
-        let mut module_map = FxHashMap::default();
+        let mut module_map = FxIndexMap::default();
         let mut module_self_bindings = FxHashMap::default();
         let graph_root = arenas.new_module(
             None,
@@ -1421,8 +1421,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             ExpnId::root(),
             DUMMY_SP,
             true,
-            &mut FxHashMap::default(),
-            &mut FxHashMap::default(),
+            &mut Default::default(),
+            &mut Default::default(),
         );
 
         let mut def_id_to_node_id = IndexVec::default();
@@ -1437,7 +1437,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         let mut invocation_parents = FxHashMap::default();
         invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
 
-        let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = tcx
+        let mut extern_prelude: FxIndexMap<Ident, ExternPreludeEntry<'_>> = tcx
             .sess
             .opts
             .externs
@@ -1536,7 +1536,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             macro_names: FxHashSet::default(),
             builtin_macros: Default::default(),
             registered_tools,
-            macro_use_prelude: FxHashMap::default(),
+            macro_use_prelude: Default::default(),
             macro_map: FxHashMap::default(),
             dummy_ext_bang: Arc::new(SyntaxExtension::dummy_bang(edition)),
             dummy_ext_derive: Arc::new(SyntaxExtension::dummy_derive(edition)),
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 984dfff3ea5..7100d89ad61 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -323,6 +323,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
     }
 
     fn check_unused_macros(&mut self) {
+        #[allow(rustc::potential_query_instability)] // FIXME
         for (_, &(node_id, ident)) in self.unused_macros.iter() {
             self.lint_buffer.buffer_lint(
                 UNUSED_MACROS,
@@ -333,10 +334,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
         }
 
         for (&def_id, unused_arms) in self.unused_macro_rules.iter() {
-            let mut unused_arms = unused_arms.iter().collect::<Vec<_>>();
-            unused_arms.sort_by_key(|&(&arm_i, _)| arm_i);
-
-            for (&arm_i, &(ident, rule_span)) in unused_arms {
+            for (&arm_i, &(ident, rule_span)) in unused_arms.to_sorted_stable_ord() {
                 if self.unused_macros.contains_key(&def_id) {
                     // We already lint the entire macro as unused
                     continue;
diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir
new file mode 100644
index 00000000000..0c8a17ff70b
--- /dev/null
+++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir
@@ -0,0 +1,81 @@
+// MIR for `foo::{closure#0}::{closure#0}` after built
+
+fn foo::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> ()
+yields ()
+ {
+    debug _task_context => _2;
+    debug f => (*(_1.0: &&Foo));
+    let mut _0: ();
+    let mut _3: &Foo;
+    let mut _4: &&Foo;
+    let mut _5: &&&Foo;
+    let mut _6: isize;
+    let mut _7: bool;
+
+    bb0: {
+        PlaceMention((*(_1.0: &&Foo)));
+        _6 = discriminant((*(*(_1.0: &&Foo))));
+        switchInt(move _6) -> [0: bb2, otherwise: bb1];
+    }
+
+    bb1: {
+        _0 = const ();
+        goto -> bb10;
+    }
+
+    bb2: {
+        falseEdge -> [real: bb5, imaginary: bb1];
+    }
+
+    bb3: {
+        goto -> bb1;
+    }
+
+    bb4: {
+        FakeRead(ForMatchedPlace(None), (*(_1.0: &&Foo)));
+        unreachable;
+    }
+
+    bb5: {
+        _3 = &fake shallow (*(*(_1.0: &&Foo)));
+        _4 = &fake shallow (*(_1.0: &&Foo));
+        _5 = &fake shallow (_1.0: &&Foo);
+        StorageLive(_7);
+        _7 = const true;
+        switchInt(move _7) -> [0: bb8, otherwise: bb7];
+    }
+
+    bb6: {
+        falseEdge -> [real: bb3, imaginary: bb1];
+    }
+
+    bb7: {
+        StorageDead(_7);
+        FakeRead(ForMatchGuard, _3);
+        FakeRead(ForMatchGuard, _4);
+        FakeRead(ForMatchGuard, _5);
+        _0 = const ();
+        goto -> bb10;
+    }
+
+    bb8: {
+        goto -> bb9;
+    }
+
+    bb9: {
+        StorageDead(_7);
+        goto -> bb6;
+    }
+
+    bb10: {
+        drop(_1) -> [return: bb11, unwind: bb12];
+    }
+
+    bb11: {
+        return;
+    }
+
+    bb12 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir
new file mode 100644
index 00000000000..bd0baddb1f8
--- /dev/null
+++ b/tests/mir-opt/async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir
@@ -0,0 +1,64 @@
+// MIR for `foo::{closure#0}::{closure#1}` after built
+
+fn foo::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_fake_read_for_by_move.rs:12:27: 15:6}, _2: ResumeTy) -> ()
+yields ()
+ {
+    debug _task_context => _2;
+    debug f => (_1.0: &Foo);
+    let mut _0: ();
+    let mut _3: &Foo;
+    let mut _4: &&Foo;
+    let mut _5: &&&Foo;
+    let mut _6: isize;
+    let mut _7: bool;
+
+    bb0: {
+        PlaceMention((_1.0: &Foo));
+        _6 = discriminant((*(_1.0: &Foo)));
+        switchInt(move _6) -> [0: bb2, otherwise: bb1];
+    }
+
+    bb1: {
+        _0 = const ();
+        goto -> bb6;
+    }
+
+    bb2: {
+        falseEdge -> [real: bb3, imaginary: bb1];
+    }
+
+    bb3: {
+        _3 = &fake shallow (*(_1.0: &Foo));
+        _4 = &fake shallow (_1.0: &Foo);
+        nop;
+        StorageLive(_7);
+        _7 = const true;
+        switchInt(move _7) -> [0: bb5, otherwise: bb4];
+    }
+
+    bb4: {
+        StorageDead(_7);
+        FakeRead(ForMatchGuard, _3);
+        FakeRead(ForMatchGuard, _4);
+        FakeRead(ForMatchGuard, _5);
+        _0 = const ();
+        goto -> bb6;
+    }
+
+    bb5: {
+        StorageDead(_7);
+        falseEdge -> [real: bb1, imaginary: bb1];
+    }
+
+    bb6: {
+        drop(_1) -> [return: bb7, unwind: bb8];
+    }
+
+    bb7: {
+        return;
+    }
+
+    bb8 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/async_closure_fake_read_for_by_move.rs b/tests/mir-opt/async_closure_fake_read_for_by_move.rs
new file mode 100644
index 00000000000..3c5aec94bbf
--- /dev/null
+++ b/tests/mir-opt/async_closure_fake_read_for_by_move.rs
@@ -0,0 +1,18 @@
+//@ edition:2021
+// skip-filecheck
+
+enum Foo {
+    Bar,
+    Baz,
+}
+
+// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#0}.built.after.mir
+// EMIT_MIR async_closure_fake_read_for_by_move.foo-{closure#0}-{closure#1}.built.after.mir
+fn foo(f: &Foo) {
+    let x = async move || match f {
+        Foo::Bar if true => {}
+        _ => {}
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/check-type-in-mir.rs b/tests/ui/const-generics/adt_const_params/check-type-in-mir.rs
new file mode 100644
index 00000000000..bec485b001c
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/check-type-in-mir.rs
@@ -0,0 +1,16 @@
+// Ensure that we actually treat `N`'s type as `Invariant<'static>` in MIR typeck.
+
+#![feature(adt_const_params)]
+
+use std::marker::ConstParamTy;
+use std::ops::Deref;
+
+#[derive(ConstParamTy, PartialEq, Eq)]
+struct Invariant<'a>(<&'a () as Deref>::Target);
+
+fn test<'a, const N: Invariant<'static>>() {
+    let x: Invariant<'a> = N;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/check-type-in-mir.stderr b/tests/ui/const-generics/adt_const_params/check-type-in-mir.stderr
new file mode 100644
index 00000000000..7e265f33f35
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/check-type-in-mir.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/check-type-in-mir.rs:12:28
+   |
+LL | fn test<'a, const N: Invariant<'static>>() {
+   |         -- lifetime `'a` defined here
+LL |     let x: Invariant<'a> = N;
+   |                            ^ assignment requires that `'a` must outlive `'static`
+   |
+   = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
+   = note: the struct `Invariant<'a>` is invariant over the parameter `'a`
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs
new file mode 100644
index 00000000000..d3bc544ed6c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.rs
@@ -0,0 +1,12 @@
+// Ensure that we actually treat `N`'s type as `&'a u32` in MIR typeck.
+
+#![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
+//~^ WARN the feature `unsized_const_params` is incomplete
+//~| WARN the feature `generic_const_parameter_types` is incomplete
+
+fn foo<'a, const N: &'a u32>() {
+    let b: &'static u32 = N;
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr
new file mode 100644
index 00000000000..3dc7ce438fa
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/check-type-in-mir.stderr
@@ -0,0 +1,27 @@
+warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/check-type-in-mir.rs:3:12
+   |
+LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/check-type-in-mir.rs:3:52
+   |
+LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information
+
+error: lifetime may not live long enough
+  --> $DIR/check-type-in-mir.rs:8:12
+   |
+LL | fn foo<'a, const N: &'a u32>() {
+   |        -- lifetime `'a` defined here
+LL |     let b: &'static u32 = N;
+   |            ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 1 previous error; 2 warnings emitted
+
diff --git a/triagebot.toml b/triagebot.toml
index 0096b22da17..293ad259910 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1082,6 +1082,7 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
     "ChrisDenton",
+    "jieyouxu",
 ]
 
 [[assign.warn_non_default_branch.exceptions]]