about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast/src/ast.rs38
-rw-r--r--compiler/rustc_ast/src/entry.rs20
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs36
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs7
-rw-r--r--compiler/rustc_ast_passes/messages.ftl10
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs31
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs11
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs23
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs76
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs110
-rw-r--r--compiler/rustc_borrowck/src/lib.rs181
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs12
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs10
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs20
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs41
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs1
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs22
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs24
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs45
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs4
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs6
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs4
-rw-r--r--compiler/rustc_feature/src/unstable.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs20
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs30
-rw-r--r--compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs47
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs413
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs19
-rw-r--r--compiler/rustc_incremental/src/persist/dirty_clean.rs8
-rw-r--r--compiler/rustc_interface/src/tests.rs3
-rw-r--r--compiler/rustc_lint/messages.ftl5
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs74
-rw-r--r--compiler/rustc_lint/src/if_let_rescope.rs430
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_middle/src/middle/region.rs6
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs9
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs30
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs8
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs20
-rw-r--r--compiler/rustc_middle/src/ty/context.rs54
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs8
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs8
-rw-r--r--compiler/rustc_middle/src/ty/rvalue_scopes.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs20
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs14
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs55
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/points.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs10
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs24
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs60
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs8
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs9
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs20
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs6
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs15
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs33
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs1
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs12
-rw-r--r--compiler/rustc_parse/src/parser/item.rs10
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs10
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs28
-rw-r--r--compiler/rustc_parse/src/parser/path.rs12
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs12
-rw-r--r--compiler/rustc_passes/src/check_attr.rs18
-rw-r--r--compiler/rustc_passes/src/liveness.rs16
-rw-r--r--compiler/rustc_passes/src/stability.rs18
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs92
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs128
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs157
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs33
-rw-r--r--compiler/rustc_resolve/src/ident.rs118
-rw-r--r--compiler/rustc_resolve/src/imports.rs108
-rw-r--r--compiler/rustc_resolve/src/late.rs273
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs37
-rw-r--r--compiler/rustc_resolve/src/lib.rs315
-rw-r--r--compiler/rustc_resolve/src/macros.rs48
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs8
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs12
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_session/src/config.rs5
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/options.rs33
-rw-r--r--compiler/rustc_session/src/parse.rs4
-rw-r--r--compiler/rustc_session/src/session.rs12
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/xtensa.rs40
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs40
-rw-r--r--compiler/rustc_target/src/spec/mod.rs76
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs6
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs28
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs15
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs38
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs6
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs10
145 files changed, 2562 insertions, 1862 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 42741bdca22..f433f2eca1a 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1188,14 +1188,7 @@ impl Expr {
     ///
     /// Does not ensure that the path resolves to a const param, the caller should check this.
     pub fn is_potential_trivial_const_arg(&self) -> bool {
-        let this = if let ExprKind::Block(block, None) = &self.kind
-            && let [stmt] = block.stmts.as_slice()
-            && let StmtKind::Expr(expr) = &stmt.kind
-        {
-            expr
-        } else {
-            self
-        };
+        let this = self.maybe_unwrap_block();
 
         if let ExprKind::Path(None, path) = &this.kind
             && path.is_potential_trivial_const_arg()
@@ -1206,6 +1199,17 @@ impl Expr {
         }
     }
 
+    pub fn maybe_unwrap_block(&self) -> &Expr {
+        if let ExprKind::Block(block, None) = &self.kind
+            && let [stmt] = block.stmts.as_slice()
+            && let StmtKind::Expr(expr) = &stmt.kind
+        {
+            expr
+        } else {
+            self
+        }
+    }
+
     pub fn to_bound(&self) -> Option<GenericBound> {
         match &self.kind {
             ExprKind::Path(None, path) => Some(GenericBound::Trait(
@@ -2602,12 +2606,12 @@ impl CoroutineKind {
         }
     }
 
-    pub fn is_async(self) -> bool {
-        matches!(self, CoroutineKind::Async { .. })
-    }
-
-    pub fn is_gen(self) -> bool {
-        matches!(self, CoroutineKind::Gen { .. })
+    pub fn as_str(self) -> &'static str {
+        match self {
+            CoroutineKind::Async { .. } => "async",
+            CoroutineKind::Gen { .. } => "gen",
+            CoroutineKind::AsyncGen { .. } => "async gen",
+        }
     }
 
     pub fn closure_id(self) -> NodeId {
@@ -3486,7 +3490,7 @@ impl From<ForeignItemKind> for ItemKind {
     fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
         match foreign_item_kind {
             ForeignItemKind::Static(box static_foreign_item) => {
-                ItemKind::Static(Box::new(static_foreign_item.into()))
+                ItemKind::Static(Box::new(static_foreign_item))
             }
             ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
             ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
@@ -3500,9 +3504,7 @@ impl TryFrom<ItemKind> for ForeignItemKind {
 
     fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
         Ok(match item_kind {
-            ItemKind::Static(box static_item) => {
-                ForeignItemKind::Static(Box::new(static_item.into()))
-            }
+            ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
             ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
             ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
             ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs
index 60a12614f06..53276e0847a 100644
--- a/compiler/rustc_ast/src/entry.rs
+++ b/compiler/rustc_ast/src/entry.rs
@@ -45,18 +45,16 @@ pub fn entry_point_type(
         EntryPointType::Start
     } else if attr::contains_name(attrs, sym::rustc_main) {
         EntryPointType::RustcMainAttr
-    } else {
-        if let Some(name) = name
-            && name == sym::main
-        {
-            if at_root {
-                // This is a top-level function so it can be `main`.
-                EntryPointType::MainNamed
-            } else {
-                EntryPointType::OtherMain
-            }
+    } else if let Some(name) = name
+        && name == sym::main
+    {
+        if at_root {
+            // This is a top-level function so it can be `main`.
+            EntryPointType::MainNamed
         } else {
-            EntryPointType::None
+            EntryPointType::OtherMain
         }
+    } else {
+        EntryPointType::None
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 4413c259efb..a9d1ee5c9c1 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -220,9 +220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             let parent_def_id = self.current_def_id_parent;
                             let node_id = self.next_node_id();
                             // HACK(min_generic_const_args): see lower_anon_const
-                            if !self.tcx.features().const_arg_path
-                                || !expr.is_potential_trivial_const_arg()
-                            {
+                            if !expr.is_potential_trivial_const_arg() {
                                 self.create_def(
                                     parent_def_id,
                                     node_id,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index b887908f904..e105026ebd1 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -387,7 +387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 let node_id = self.next_node_id();
 
                 // HACK(min_generic_const_args): see lower_anon_const
-                if !self.tcx.features().const_arg_path || !arg.is_potential_trivial_const_arg() {
+                if !arg.is_potential_trivial_const_arg() {
                     // Add a definition for the in-band const def.
                     self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
                 }
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 23729124e21..f90a0612db6 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -78,26 +78,24 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
 
         // Make sure that the DepNode of some node coincides with the HirId
         // owner of that node.
-        if cfg!(debug_assertions) {
-            if hir_id.owner != self.owner {
-                span_bug!(
-                    span,
-                    "inconsistent HirId at `{:?}` for `{:?}`: \
+        if cfg!(debug_assertions) && hir_id.owner != self.owner {
+            span_bug!(
+                span,
+                "inconsistent HirId at `{:?}` for `{:?}`: \
                      current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
-                    self.tcx.sess.source_map().span_to_diagnostic_string(span),
-                    node,
-                    self.tcx
-                        .definitions_untracked()
-                        .def_path(self.owner.def_id)
-                        .to_string_no_crate_verbose(),
-                    self.owner,
-                    self.tcx
-                        .definitions_untracked()
-                        .def_path(hir_id.owner.def_id)
-                        .to_string_no_crate_verbose(),
-                    hir_id.owner,
-                )
-            }
+                self.tcx.sess.source_map().span_to_diagnostic_string(span),
+                node,
+                self.tcx
+                    .definitions_untracked()
+                    .def_path(self.owner.def_id)
+                    .to_string_no_crate_verbose(),
+                self.owner,
+                self.tcx
+                    .definitions_untracked()
+                    .def_path(hir_id.owner.def_id)
+                    .to_string_no_crate_verbose(),
+                hir_id.owner,
+            )
         }
 
         self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c8ec8f308a8..73c604bf28a 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -628,13 +628,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                                 .map_or(Const::No, |attr| Const::Yes(attr.span)),
                             _ => Const::No,
                         }
+                    } else if self.tcx.is_const_trait(def_id) {
+                        // FIXME(effects) span
+                        Const::Yes(self.tcx.def_ident_span(def_id).unwrap())
                     } else {
-                        if self.tcx.is_const_trait(def_id) {
-                            // FIXME(effects) span
-                            Const::Yes(self.tcx.def_ident_span(def_id).unwrap())
-                        } else {
-                            Const::No
-                        }
+                        Const::No
                     }
                 } else {
                     Const::No
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 754fbae4d02..efd3ae336af 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2335,7 +2335,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         span: Span,
     ) -> &'hir hir::ConstArg<'hir> {
         let ct_kind = match res {
-            Res::Def(DefKind::ConstParam, _) if self.tcx.features().const_arg_path => {
+            Res::Def(DefKind::ConstParam, _) => {
                 let qpath = self.lower_qpath(
                     ty_id,
                     &None,
@@ -2410,8 +2410,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
         debug!("res={:?}", maybe_res);
         // FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
-        if self.tcx.features().const_arg_path
-            && let Some(res) = maybe_res
+        if let Some(res) = maybe_res
             && let Res::Def(DefKind::ConstParam, _) = res
             && let ExprKind::Path(qself, path) = &expr.kind
         {
@@ -2442,7 +2441,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     /// See [`hir::ConstArg`] for when to use this function vs
     /// [`Self::lower_anon_const_to_const_arg`].
     fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
-        if self.tcx.features().const_arg_path && c.value.is_potential_trivial_const_arg() {
+        if c.value.is_potential_trivial_const_arg() {
             // HACK(min_generic_const_args): see DefCollector::visit_anon_const
             // Over there, we guess if this is a bare param and only create a def if
             // we think it's not. However we may can guess wrong (see there for example)
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index df5c639382f..c361c35b723 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -40,15 +40,15 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
 
 ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
 
-ast_passes_const_and_async = functions cannot be both `const` and `async`
-    .const = `const` because of this
-    .async = `async` because of this
-    .label = {""}
-
 ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
     .const = `const` because of this
     .variadic = C-variadic because of this
 
+ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
+    .const = `const` because of this
+    .coroutine = `{$coroutine_kind}` because of this
+    .label = {""}
+
 ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
 
 ast_passes_const_without_body =
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index ed9672a9e79..93881f5ed42 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -447,13 +447,13 @@ impl<'a> AstValidator<'a> {
     fn check_item_safety(&self, span: Span, safety: Safety) {
         match self.extern_mod_safety {
             Some(extern_safety) => {
-                if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) {
-                    if extern_safety == Safety::Default {
-                        self.dcx().emit_err(errors::InvalidSafetyOnExtern {
-                            item_span: span,
-                            block: Some(self.current_extern_span().shrink_to_lo()),
-                        });
-                    }
+                if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
+                    && extern_safety == Safety::Default
+                {
+                    self.dcx().emit_err(errors::InvalidSafetyOnExtern {
+                        item_span: span,
+                        block: Some(self.current_extern_span().shrink_to_lo()),
+                    });
                 }
             }
             None => {
@@ -1418,21 +1418,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
         // Functions cannot both be `const async` or `const gen`
         if let Some(&FnHeader {
-            constness: Const::Yes(cspan),
+            constness: Const::Yes(const_span),
             coroutine_kind: Some(coroutine_kind),
             ..
         }) = fk.header()
         {
-            let aspan = match coroutine_kind {
-                CoroutineKind::Async { span: aspan, .. }
-                | CoroutineKind::Gen { span: aspan, .. }
-                | CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
-            };
-            // FIXME(gen_blocks): Report a different error for `const gen`
-            self.dcx().emit_err(errors::ConstAndAsync {
-                spans: vec![cspan, aspan],
-                cspan,
-                aspan,
+            self.dcx().emit_err(errors::ConstAndCoroutine {
+                spans: vec![coroutine_kind.span(), const_span],
+                const_span,
+                coroutine_span: coroutine_kind.span(),
+                coroutine_kind: coroutine_kind.as_str(),
                 span,
             });
         }
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 67c0396333c..5cce47ce7bd 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -657,16 +657,17 @@ pub(crate) enum TildeConstReason {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_const_and_async)]
-pub(crate) struct ConstAndAsync {
+#[diag(ast_passes_const_and_coroutine)]
+pub(crate) struct ConstAndCoroutine {
     #[primary_span]
     pub spans: Vec<Span>,
     #[label(ast_passes_const)]
-    pub cspan: Span,
-    #[label(ast_passes_async)]
-    pub aspan: Span,
+    pub const_span: Span,
+    #[label(ast_passes_coroutine)]
+    pub coroutine_span: Span,
     #[label]
     pub span: Span,
+    pub coroutine_kind: &'static str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 39994ad784a..6725920746b 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::{RegionVid, TyCtxt};
 use rustc_mir_dataflow::fmt::DebugWithContext;
 use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces};
-use rustc_mir_dataflow::{Analysis, AnalysisDomain, GenKill, Results, ResultsVisitable};
+use rustc_mir_dataflow::{Analysis, AnalysisDomain, Forward, GenKill, Results, ResultsVisitable};
 use tracing::debug;
 
 use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
@@ -23,26 +23,25 @@ pub(crate) struct BorrowckResults<'a, 'tcx> {
 
 /// The transient state of the dataflow analyses used by the borrow checker.
 #[derive(Debug)]
-pub(crate) struct BorrowckFlowState<'a, 'tcx> {
+pub(crate) struct BorrowckDomain<'a, 'tcx> {
     pub(crate) borrows: <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
     pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
     pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
 }
 
 impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
-    // All three analyses are forward, but we have to use just one here.
-    type Direction = <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Direction;
-    type FlowState = BorrowckFlowState<'a, 'tcx>;
+    type Direction = Forward;
+    type Domain = BorrowckDomain<'a, 'tcx>;
 
-    fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
-        BorrowckFlowState {
+    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
+        BorrowckDomain {
             borrows: self.borrows.analysis.bottom_value(body),
             uninits: self.uninits.analysis.bottom_value(body),
             ever_inits: self.ever_inits.analysis.bottom_value(body),
         }
     }
 
-    fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
+    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock) {
         state.borrows.clone_from(self.borrows.entry_set_for_block(block));
         state.uninits.clone_from(self.uninits.entry_set_for_block(block));
         state.ever_inits.clone_from(self.ever_inits.entry_set_for_block(block));
@@ -50,7 +49,7 @@ impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
 
     fn reconstruct_before_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
@@ -61,7 +60,7 @@ impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
 
     fn reconstruct_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
@@ -72,7 +71,7 @@ impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
 
     fn reconstruct_before_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
@@ -83,7 +82,7 @@ impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
 
     fn reconstruct_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 12ae2c29e8b..4a31aee5c96 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1999,19 +1999,32 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     ) {
         let used_in_call = matches!(
             explanation,
-            BorrowExplanation::UsedLater(LaterUseKind::Call | LaterUseKind::Other, _call_span, _)
+            BorrowExplanation::UsedLater(
+                _,
+                LaterUseKind::Call | LaterUseKind::Other,
+                _call_span,
+                _
+            )
         );
         if !used_in_call {
             debug!("not later used in call");
             return;
         }
+        if matches!(
+            self.body.local_decls[issued_borrow.borrowed_place.local].local_info(),
+            LocalInfo::IfThenRescopeTemp { .. }
+        ) {
+            // A better suggestion will be issued by the `if_let_rescope` lint
+            return;
+        }
 
-        let use_span =
-            if let BorrowExplanation::UsedLater(LaterUseKind::Other, use_span, _) = explanation {
-                Some(use_span)
-            } else {
-                None
-            };
+        let use_span = if let BorrowExplanation::UsedLater(_, LaterUseKind::Other, use_span, _) =
+            explanation
+        {
+            Some(use_span)
+        } else {
+            None
+        };
 
         let outer_call_loc =
             if let TwoPhaseActivation::ActivatedAt(loc) = issued_borrow.activation_location {
@@ -2574,33 +2587,31 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         }
         impl<'hir> Visitor<'hir> for ExpressionFinder<'hir> {
             fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
-                if e.span.contains(self.capture_span) {
-                    if let hir::ExprKind::Closure(&hir::Closure {
+                if e.span.contains(self.capture_span)
+                    && let hir::ExprKind::Closure(&hir::Closure {
                         kind: hir::ClosureKind::Closure,
                         body,
                         fn_arg_span,
                         fn_decl: hir::FnDecl { inputs, .. },
                         ..
                     }) = e.kind
-                        && let hir::Node::Expr(body) = self.tcx.hir_node(body.hir_id)
-                    {
-                        self.suggest_arg = "this: &Self".to_string();
-                        if inputs.len() > 0 {
-                            self.suggest_arg.push_str(", ");
-                        }
-                        self.in_closure = true;
-                        self.closure_arg_span = fn_arg_span;
-                        self.visit_expr(body);
-                        self.in_closure = false;
+                    && let hir::Node::Expr(body) = self.tcx.hir_node(body.hir_id)
+                {
+                    self.suggest_arg = "this: &Self".to_string();
+                    if inputs.len() > 0 {
+                        self.suggest_arg.push_str(", ");
                     }
+                    self.in_closure = true;
+                    self.closure_arg_span = fn_arg_span;
+                    self.visit_expr(body);
+                    self.in_closure = false;
                 }
-                if let hir::Expr { kind: hir::ExprKind::Path(path), .. } = e {
-                    if let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path
-                        && seg.ident.name == kw::SelfLower
-                        && self.in_closure
-                    {
-                        self.closure_change_spans.push(e.span);
-                    }
+                if let hir::Expr { kind: hir::ExprKind::Path(path), .. } = e
+                    && let hir::QPath::Resolved(_, hir::Path { segments: [seg], .. }) = path
+                    && seg.ident.name == kw::SelfLower
+                    && self.in_closure
+                {
+                    self.closure_change_spans.push(e.span);
                 }
                 hir::intravisit::walk_expr(self, e);
             }
@@ -2609,8 +2620,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } =
                     local.pat
                     && let Some(init) = local.init
-                {
-                    if let hir::Expr {
+                    && let hir::Expr {
                         kind:
                             hir::ExprKind::Closure(&hir::Closure {
                                 kind: hir::ClosureKind::Closure,
@@ -2618,11 +2628,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                             }),
                         ..
                     } = init
-                        && init.span.contains(self.capture_span)
-                    {
-                        self.closure_local_id = Some(*hir_id);
-                    }
+                    && init.span.contains(self.capture_span)
+                {
+                    self.closure_local_id = Some(*hir_id);
                 }
+
                 hir::intravisit::walk_local(self, local);
             }
 
@@ -2862,7 +2872,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             // and `move` will not help here.
             (
                 Some(name),
-                BorrowExplanation::UsedLater(LaterUseKind::ClosureCapture, var_or_use_span, _),
+                BorrowExplanation::UsedLater(_, LaterUseKind::ClosureCapture, var_or_use_span, _),
             ) if borrow_spans.for_coroutine() || borrow_spans.for_closure() => self
                 .report_escaping_closure_capture(
                     borrow_spans,
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 419e72df00b..d9b5fd8b5c1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -30,7 +30,7 @@ use crate::{MirBorrowckCtxt, WriteKind};
 
 #[derive(Debug)]
 pub(crate) enum BorrowExplanation<'tcx> {
-    UsedLater(LaterUseKind, Span, Option<Span>),
+    UsedLater(Local, LaterUseKind, Span, Option<Span>),
     UsedLaterInLoop(LaterUseKind, Span, Option<Span>),
     UsedLaterWhenDropped {
         drop_loc: Location,
@@ -99,7 +99,12 @@ impl<'tcx> BorrowExplanation<'tcx> {
             }
         }
         match *self {
-            BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
+            BorrowExplanation::UsedLater(
+                dropped_local,
+                later_use_kind,
+                var_or_use_span,
+                path_span,
+            ) => {
                 let message = match later_use_kind {
                     LaterUseKind::TraitCapture => "captured here by trait object",
                     LaterUseKind::ClosureCapture => "captured here by closure",
@@ -107,9 +112,26 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     LaterUseKind::FakeLetRead => "stored here",
                     LaterUseKind::Other => "used here",
                 };
-                // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
-                if path_span.map(|path_span| path_span == var_or_use_span).unwrap_or(true) {
-                    if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
+                let local_decl = &body.local_decls[dropped_local];
+
+                if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info()
+                    && let Some((_, hir::Node::Expr(expr))) = tcx.hir().parent_iter(if_then).next()
+                    && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
+                    && let hir::ExprKind::Let(&hir::LetExpr {
+                        span: _,
+                        pat,
+                        init,
+                        // FIXME(#101728): enable rewrite when type ascription is stabilized again
+                        ty: None,
+                        recovered: _,
+                    }) = cond.kind
+                    && pat.span.can_be_used_for_suggestions()
+                    && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
+                {
+                    suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
+                } else if path_span.map_or(true, |path_span| path_span == var_or_use_span) {
+                    // We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
+                    if borrow_span.map_or(true, |sp| !sp.overlaps(var_or_use_span)) {
                         err.span_label(
                             var_or_use_span,
                             format!("{borrow_desc}borrow later {message}"),
@@ -255,6 +277,22 @@ impl<'tcx> BorrowExplanation<'tcx> {
                                     Applicability::MaybeIncorrect,
                                 );
                             };
+                        } else if let &LocalInfo::IfThenRescopeTemp { if_then } =
+                            local_decl.local_info()
+                            && let hir::Node::Expr(expr) = tcx.hir_node(if_then)
+                            && let hir::ExprKind::If(cond, conseq, alt) = expr.kind
+                            && let hir::ExprKind::Let(&hir::LetExpr {
+                                span: _,
+                                pat,
+                                init,
+                                // FIXME(#101728): enable rewrite when type ascription is stabilized again
+                                ty: None,
+                                recovered: _,
+                            }) = cond.kind
+                            && pat.span.can_be_used_for_suggestions()
+                            && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
+                        {
+                            suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
                         }
                     }
                 }
@@ -390,6 +428,53 @@ impl<'tcx> BorrowExplanation<'tcx> {
     }
 }
 
+fn suggest_rewrite_if_let(
+    tcx: TyCtxt<'_>,
+    expr: &hir::Expr<'_>,
+    pat: &str,
+    init: &hir::Expr<'_>,
+    conseq: &hir::Expr<'_>,
+    alt: Option<&hir::Expr<'_>>,
+    err: &mut Diag<'_>,
+) {
+    let source_map = tcx.sess.source_map();
+    err.span_note(
+        source_map.end_point(conseq.span),
+        "lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead",
+    );
+    if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() {
+        let needs_block = if let Some(hir::Node::Expr(expr)) =
+            alt.and_then(|alt| tcx.hir().parent_iter(alt.hir_id).next()).map(|(_, node)| node)
+        {
+            matches!(expr.kind, hir::ExprKind::If(..))
+        } else {
+            false
+        };
+        let mut sugg = vec![
+            (
+                expr.span.shrink_to_lo().between(init.span),
+                if needs_block { "{ match ".into() } else { "match ".into() },
+            ),
+            (conseq.span.shrink_to_lo(), format!(" {{ {pat} => ")),
+        ];
+        let expr_end = expr.span.shrink_to_hi();
+        let mut expr_end_code;
+        if let Some(alt) = alt {
+            sugg.push((conseq.span.between(alt.span), " _ => ".into()));
+            expr_end_code = "}".to_string();
+        } else {
+            expr_end_code = " _ => {} }".into();
+        }
+        expr_end_code.push('}');
+        sugg.push((expr_end, expr_end_code));
+        err.multipart_suggestion(
+            "consider rewriting the `if` into `match` which preserves the extended lifetime",
+            sugg,
+            Applicability::MaybeIncorrect,
+        );
+    }
+}
+
 impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
     fn free_region_constraint_info(
         &self,
@@ -465,14 +550,21 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
                     .or_else(|| self.borrow_spans(span, location));
 
                 if use_in_later_iteration_of_loop {
-                    let later_use = self.later_use_kind(borrow, spans, use_location);
-                    BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1, later_use.2)
+                    let (later_use_kind, var_or_use_span, path_span) =
+                        self.later_use_kind(borrow, spans, use_location);
+                    BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span, path_span)
                 } else {
                     // Check if the location represents a `FakeRead`, and adapt the error
                     // message to the `FakeReadCause` it is from: in particular,
                     // the ones inserted in optimized `let var = <expr>` patterns.
-                    let later_use = self.later_use_kind(borrow, spans, location);
-                    BorrowExplanation::UsedLater(later_use.0, later_use.1, later_use.2)
+                    let (later_use_kind, var_or_use_span, path_span) =
+                        self.later_use_kind(borrow, spans, location);
+                    BorrowExplanation::UsedLater(
+                        borrow.borrowed_place.local,
+                        later_use_kind,
+                        var_or_use_span,
+                        path_span,
+                    )
                 }
             }
 
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index d5f297a5913..58e73030749 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -83,7 +83,7 @@ mod util;
 pub mod consumers;
 
 use borrow_set::{BorrowData, BorrowSet};
-use dataflow::{BorrowIndex, BorrowckFlowState as Flows, BorrowckResults, Borrows};
+use dataflow::{BorrowIndex, BorrowckDomain, BorrowckResults, Borrows};
 use nll::PoloniusOutput;
 use place_ext::PlaceExt;
 use places_conflict::{places_conflict, PlaceConflictBias};
@@ -602,25 +602,25 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
 impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
     for MirBorrowckCtxt<'a, '_, 'tcx>
 {
-    type FlowState = Flows<'a, 'tcx>;
+    type Domain = BorrowckDomain<'a, 'tcx>;
 
     fn visit_statement_before_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
         stmt: &'a Statement<'tcx>,
         location: Location,
     ) {
-        debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
+        debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, state);
         let span = stmt.source_info.span;
 
-        self.check_activations(location, span, flow_state);
+        self.check_activations(location, span, state);
 
         match &stmt.kind {
             StatementKind::Assign(box (lhs, rhs)) => {
-                self.consume_rvalue(location, (rhs, span), flow_state);
+                self.consume_rvalue(location, (rhs, span), state);
 
-                self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
+                self.mutate_place(location, (*lhs, span), Shallow(None), state);
             }
             StatementKind::FakeRead(box (_, place)) => {
                 // Read for match doesn't access any memory and is used to
@@ -637,11 +637,11 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                     location,
                     InitializationRequiringAction::Use,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
             StatementKind::Intrinsic(box kind) => match kind {
-                NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
+                NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), state),
                 NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
                     span,
                     "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
@@ -662,7 +662,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                     (Place::from(*local), span),
                     (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
-                    flow_state,
+                    state,
                 );
             }
             StatementKind::Nop
@@ -677,18 +677,18 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
     fn visit_terminator_before_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
         term: &'a Terminator<'tcx>,
         loc: Location,
     ) {
-        debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
+        debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, state);
         let span = term.source_info.span;
 
-        self.check_activations(loc, span, flow_state);
+        self.check_activations(loc, span, state);
 
         match &term.kind {
             TerminatorKind::SwitchInt { discr, targets: _ } => {
-                self.consume_operand(loc, (discr, span), flow_state);
+                self.consume_operand(loc, (discr, span), state);
             }
             TerminatorKind::Drop { place, target: _, unwind: _, replace } => {
                 debug!(
@@ -704,7 +704,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                     (*place, span),
                     (AccessDepth::Drop, Write(write_kind)),
                     LocalMutationIsAllowed::Yes,
-                    flow_state,
+                    state,
                 );
             }
             TerminatorKind::Call {
@@ -716,29 +716,29 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                 call_source: _,
                 fn_span: _,
             } => {
-                self.consume_operand(loc, (func, span), flow_state);
+                self.consume_operand(loc, (func, span), state);
                 for arg in args {
-                    self.consume_operand(loc, (&arg.node, arg.span), flow_state);
+                    self.consume_operand(loc, (&arg.node, arg.span), state);
                 }
-                self.mutate_place(loc, (*destination, span), Deep, flow_state);
+                self.mutate_place(loc, (*destination, span), Deep, state);
             }
             TerminatorKind::TailCall { func, args, fn_span: _ } => {
-                self.consume_operand(loc, (func, span), flow_state);
+                self.consume_operand(loc, (func, span), state);
                 for arg in args {
-                    self.consume_operand(loc, (&arg.node, arg.span), flow_state);
+                    self.consume_operand(loc, (&arg.node, arg.span), state);
                 }
             }
             TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
-                self.consume_operand(loc, (cond, span), flow_state);
+                self.consume_operand(loc, (cond, span), state);
                 if let AssertKind::BoundsCheck { len, index } = &**msg {
-                    self.consume_operand(loc, (len, span), flow_state);
-                    self.consume_operand(loc, (index, span), flow_state);
+                    self.consume_operand(loc, (len, span), state);
+                    self.consume_operand(loc, (index, span), state);
                 }
             }
 
             TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
-                self.consume_operand(loc, (value, span), flow_state);
-                self.mutate_place(loc, (*resume_arg, span), Deep, flow_state);
+                self.consume_operand(loc, (value, span), state);
+                self.mutate_place(loc, (*resume_arg, span), Deep, state);
             }
 
             TerminatorKind::InlineAsm {
@@ -752,22 +752,17 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                 for op in operands {
                     match op {
                         InlineAsmOperand::In { reg: _, value } => {
-                            self.consume_operand(loc, (value, span), flow_state);
+                            self.consume_operand(loc, (value, span), state);
                         }
                         InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
                             if let Some(place) = place {
-                                self.mutate_place(loc, (*place, span), Shallow(None), flow_state);
+                                self.mutate_place(loc, (*place, span), Shallow(None), state);
                             }
                         }
                         InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
-                            self.consume_operand(loc, (in_value, span), flow_state);
+                            self.consume_operand(loc, (in_value, span), state);
                             if let &Some(out_place) = out_place {
-                                self.mutate_place(
-                                    loc,
-                                    (out_place, span),
-                                    Shallow(None),
-                                    flow_state,
-                                );
+                                self.mutate_place(loc, (out_place, span), Shallow(None), state);
                             }
                         }
                         InlineAsmOperand::Const { value: _ }
@@ -794,7 +789,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
     fn visit_terminator_after_primary_effect(
         &mut self,
         _results: &mut R,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
         term: &'a Terminator<'tcx>,
         loc: Location,
     ) {
@@ -805,7 +800,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                 if self.movable_coroutine {
                     // Look for any active borrows to locals
                     let borrow_set = self.borrow_set.clone();
-                    for i in flow_state.borrows.iter() {
+                    for i in state.borrows.iter() {
                         let borrow = &borrow_set[i];
                         self.check_for_local_borrow(borrow, span);
                     }
@@ -821,7 +816,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
                 // StorageDead, but we don't always emit those (notably on unwind paths),
                 // so this "extra check" serves as a kind of backup.
                 let borrow_set = self.borrow_set.clone();
-                for i in flow_state.borrows.iter() {
+                for i in state.borrows.iter() {
                     let borrow = &borrow_set[i];
                     self.check_for_invalidation_at_exit(loc, borrow, span);
                 }
@@ -989,7 +984,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         place_span: (Place<'tcx>, Span),
         kind: (AccessDepth, ReadOrWrite),
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
         let (sd, rw) = kind;
 
@@ -1020,11 +1015,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             place_span,
             rw,
             is_local_mutation_allowed,
-            flow_state,
+            state,
             location,
         );
-        let conflict_error =
-            self.check_access_for_conflict(location, place_span, sd, rw, flow_state);
+        let conflict_error = self.check_access_for_conflict(location, place_span, sd, rw, state);
 
         if conflict_error || mutability_error {
             debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind);
@@ -1032,14 +1026,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self, flow_state))]
+    #[instrument(level = "debug", skip(self, state))]
     fn check_access_for_conflict(
         &mut self,
         location: Location,
         place_span: (Place<'tcx>, Span),
         sd: AccessDepth,
         rw: ReadOrWrite,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) -> bool {
         let mut error_reported = false;
         let borrow_set = Rc::clone(&self.borrow_set);
@@ -1054,7 +1048,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             }
             &polonius_output
         } else {
-            &flow_state.borrows
+            &state.borrows
         };
 
         each_borrow_involving_path(
@@ -1180,17 +1174,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         place_span: (Place<'tcx>, Span),
         kind: AccessDepth,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
         // Write of P[i] or *P requires P init'd.
-        self.check_if_assigned_path_is_moved(location, place_span, flow_state);
+        self.check_if_assigned_path_is_moved(location, place_span, state);
 
         self.access_place(
             location,
             place_span,
             (kind, Write(WriteKind::Mutate)),
             LocalMutationIsAllowed::No,
-            flow_state,
+            state,
         );
     }
 
@@ -1198,7 +1192,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (rvalue, span): (&'a Rvalue<'tcx>, Span),
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
         match rvalue {
             &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@@ -1224,7 +1218,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     access_kind,
                     LocalMutationIsAllowed::No,
-                    flow_state,
+                    state,
                 );
 
                 let action = if bk == BorrowKind::Fake(FakeBorrowKind::Shallow) {
@@ -1237,7 +1231,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     location,
                     action,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
 
@@ -1257,14 +1251,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     access_kind,
                     LocalMutationIsAllowed::No,
-                    flow_state,
+                    state,
                 );
 
                 self.check_if_path_or_subpath_is_moved(
                     location,
                     InitializationRequiringAction::Borrow,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
 
@@ -1275,7 +1269,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             | Rvalue::UnaryOp(_ /*un_op*/, operand)
             | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
             | Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
-                self.consume_operand(location, (operand, span), flow_state)
+                self.consume_operand(location, (operand, span), state)
             }
 
             &Rvalue::CopyForDeref(place) => {
@@ -1284,7 +1278,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     (Deep, Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
-                    flow_state,
+                    state,
                 );
 
                 // Finally, check if path was already moved.
@@ -1292,7 +1286,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     location,
                     InitializationRequiringAction::Use,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
 
@@ -1307,19 +1301,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     (Shallow(af), Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
-                    flow_state,
+                    state,
                 );
                 self.check_if_path_or_subpath_is_moved(
                     location,
                     InitializationRequiringAction::Use,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
 
             Rvalue::BinaryOp(_bin_op, box (operand1, operand2)) => {
-                self.consume_operand(location, (operand1, span), flow_state);
-                self.consume_operand(location, (operand2, span), flow_state);
+                self.consume_operand(location, (operand1, span), state);
+                self.consume_operand(location, (operand2, span), state);
             }
 
             Rvalue::NullaryOp(_op, _ty) => {
@@ -1349,7 +1343,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 }
 
                 for operand in operands {
-                    self.consume_operand(location, (operand, span), flow_state);
+                    self.consume_operand(location, (operand, span), state);
                 }
             }
         }
@@ -1456,7 +1450,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (operand, span): (&'a Operand<'tcx>, Span),
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
         match *operand {
             Operand::Copy(place) => {
@@ -1467,7 +1461,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     (Deep, Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
-                    flow_state,
+                    state,
                 );
 
                 // Finally, check if path was already moved.
@@ -1475,7 +1469,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     location,
                     InitializationRequiringAction::Use,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
             Operand::Move(place) => {
@@ -1488,7 +1482,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     (place, span),
                     (Deep, Write(WriteKind::Move)),
                     LocalMutationIsAllowed::Yes,
-                    flow_state,
+                    state,
                 );
 
                 // Finally, check if path was already moved.
@@ -1496,7 +1490,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                     location,
                     InitializationRequiringAction::Use,
                     (place.as_ref(), span),
-                    flow_state,
+                    state,
                 );
             }
             Operand::Constant(_) => {}
@@ -1576,7 +1570,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         }
     }
 
-    fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'a, 'tcx>) {
+    fn check_activations(
+        &mut self,
+        location: Location,
+        span: Span,
+        state: &BorrowckDomain<'a, 'tcx>,
+    ) {
         // Two-phase borrow support: For each activation that is newly
         // generated at this statement, check if it interferes with
         // another borrow.
@@ -1595,7 +1594,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 (borrow.borrowed_place, span),
                 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
                 LocalMutationIsAllowed::No,
-                flow_state,
+                state,
             );
             // We do not need to call `check_if_path_or_subpath_is_moved`
             // again, as we already called it when we made the
@@ -1739,9 +1738,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
-        let maybe_uninits = &flow_state.uninits;
+        let maybe_uninits = &state.uninits;
 
         // Bad scenarios:
         //
@@ -1844,9 +1843,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         location: Location,
         desired_action: InitializationRequiringAction,
         place_span: (PlaceRef<'tcx>, Span),
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
-        let maybe_uninits = &flow_state.uninits;
+        let maybe_uninits = &state.uninits;
 
         // Bad scenarios:
         //
@@ -1863,7 +1862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         //    must have been initialized for the use to be sound.
         // 6. Move of `a.b.c` then reinit of `a.b.c.d`, use of `a.b.c.d`
 
-        self.check_if_full_path_is_moved(location, desired_action, place_span, flow_state);
+        self.check_if_full_path_is_moved(location, desired_action, place_span, state);
 
         if let Some((place_base, ProjectionElem::Subslice { from, to, from_end: false })) =
             place_span.0.last_projection()
@@ -1943,7 +1942,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         &mut self,
         location: Location,
         (place, span): (Place<'tcx>, Span),
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
 
@@ -1965,7 +1964,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 ProjectionElem::Deref => {
                     self.check_if_full_path_is_moved(
                         location, InitializationRequiringAction::Use,
-                        (place_base, span), flow_state);
+                        (place_base, span), state);
                     // (base initialized; no need to
                     // recur further)
                     break;
@@ -1985,7 +1984,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                         ty::Adt(def, _) if def.has_dtor(tcx) => {
                             self.check_if_path_or_subpath_is_moved(
                                 location, InitializationRequiringAction::Assignment,
-                                (place_base, span), flow_state);
+                                (place_base, span), state);
 
                             // (base initialized; no need to
                             // recur further)
@@ -1995,7 +1994,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                         // Once `let s; s.x = V; read(s.x);`,
                         // is allowed, remove this match arm.
                         ty::Adt(..) | ty::Tuple(..) => {
-                            check_parent_of_field(self, location, place_base, span, flow_state);
+                            check_parent_of_field(self, location, place_base, span, state);
                         }
 
                         _ => {}
@@ -2009,7 +2008,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             location: Location,
             base: PlaceRef<'tcx>,
             span: Span,
-            flow_state: &Flows<'a, 'tcx>,
+            state: &BorrowckDomain<'a, 'tcx>,
         ) {
             // rust-lang/rust#21232: Until Rust allows reads from the
             // initialized parts of partially initialized structs, we
@@ -2042,7 +2041,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
 
             // Shallow so that we'll stop at any dereference; we'll
             // report errors about issues with such bases elsewhere.
-            let maybe_uninits = &flow_state.uninits;
+            let maybe_uninits = &state.uninits;
 
             // Find the shortest uninitialized prefix you can reach
             // without going over a Deref.
@@ -2069,12 +2068,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 // no move out from an earlier location) then this is an attempt at initialization
                 // of the union - we should error in that case.
                 let tcx = this.infcx.tcx;
-                if base.ty(this.body(), tcx).ty.is_union() {
-                    if this.move_data.path_map[mpi].iter().any(|moi| {
+                if base.ty(this.body(), tcx).ty.is_union()
+                    && this.move_data.path_map[mpi].iter().any(|moi| {
                         this.move_data.moves[*moi].source.is_predecessor_of(location, this.body)
-                    }) {
-                        return;
-                    }
+                    })
+                {
+                    return;
                 }
 
                 this.report_use_of_moved_or_uninitialized(
@@ -2100,7 +2099,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         (place, span): (Place<'tcx>, Span),
         kind: ReadOrWrite,
         is_local_mutation_allowed: LocalMutationIsAllowed,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
         location: Location,
     ) -> bool {
         debug!(
@@ -2124,7 +2123,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 };
                 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
                     Ok(root_place) => {
-                        self.add_used_mut(root_place, flow_state);
+                        self.add_used_mut(root_place, state);
                         return false;
                     }
                     Err(place_err) => {
@@ -2136,7 +2135,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
             Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => {
                 match self.is_mutable(place.as_ref(), is_local_mutation_allowed) {
                     Ok(root_place) => {
-                        self.add_used_mut(root_place, flow_state);
+                        self.add_used_mut(root_place, state);
                         return false;
                     }
                     Err(place_err) => {
@@ -2194,7 +2193,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         // partial initialization, do not complain about mutability
         // errors except for actual mutation (as opposed to an attempt
         // to do a partial initialization).
-        let previously_initialized = self.is_local_ever_initialized(place.local, flow_state);
+        let previously_initialized = self.is_local_ever_initialized(place.local, state);
 
         // at this point, we have set up the error reporting state.
         if let Some(init_index) = previously_initialized {
@@ -2216,22 +2215,22 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
     fn is_local_ever_initialized(
         &self,
         local: Local,
-        flow_state: &Flows<'a, 'tcx>,
+        state: &BorrowckDomain<'a, 'tcx>,
     ) -> Option<InitIndex> {
         let mpi = self.move_data.rev_lookup.find_local(local)?;
         let ii = &self.move_data.init_path_map[mpi];
-        ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied()
+        ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied()
     }
 
     /// Adds the place into the used mutable variables set
-    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'a, 'tcx>) {
+    fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain<'a, 'tcx>) {
         match root_place {
             RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
                 // If the local may have been initialized, and it is now currently being
                 // mutated, then it is justified to be annotated with the `mut`
                 // keyword, since the mutation may be a possible reassignment.
                 if is_local_mutation_allowed != LocalMutationIsAllowed::Yes
-                    && self.is_local_ever_initialized(local, flow_state).is_some()
+                    && self.is_local_ever_initialized(local, state).is_some()
                 {
                     self.used_mut.insert(local);
                 }
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index d62f2067729..30dc062ae7c 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -118,10 +118,8 @@ impl LivenessValues {
         debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
         if let Some(points) = &mut self.points {
             points.insert(region, point);
-        } else {
-            if self.elements.point_in_range(point) {
-                self.live_regions.as_mut().unwrap().insert(region);
-            }
+        } else if self.elements.point_in_range(point) {
+            self.live_regions.as_mut().unwrap().insert(region);
         }
 
         // When available, record the loans flowing into this region as live at the given point.
@@ -137,10 +135,8 @@ impl LivenessValues {
         debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
         if let Some(this) = &mut self.points {
             this.union_row(region, points);
-        } else {
-            if points.iter().any(|point| self.elements.point_in_range(point)) {
-                self.live_regions.as_mut().unwrap().insert(region);
-            }
+        } else if points.iter().any(|point| self.elements.point_in_range(point)) {
+            self.live_regions.as_mut().unwrap().insert(region);
         }
 
         // When available, record the loans flowing into this region as live at the given points.
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 4d47863ae76..1ac27573453 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -353,11 +353,11 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
             let location = self.cx.elements.to_location(drop_point);
             debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
 
-            if self.cx.initialized_at_terminator(location.block, mpi) {
-                if self.drop_live_at.insert(drop_point) {
-                    self.drop_locations.push(location);
-                    self.stack.push(drop_point);
-                }
+            if self.cx.initialized_at_terminator(location.block, mpi)
+                && self.drop_live_at.insert(drop_point)
+            {
+                self.drop_locations.push(location);
+                self.stack.push(drop_point);
             }
         }
 
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index d6248899655..0e1ec3b3cad 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -235,13 +235,11 @@ pub fn parse_asm_args<'a>(
                 continue;
             }
             args.named_args.insert(name, slot);
-        } else {
-            if !args.named_args.is_empty() || !args.reg_args.is_empty() {
-                let named = args.named_args.values().map(|p| args.operands[*p].1).collect();
-                let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect();
+        } else if !args.named_args.is_empty() || !args.reg_args.is_empty() {
+            let named = args.named_args.values().map(|p| args.operands[*p].1).collect();
+            let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect();
 
-                dcx.emit_err(errors::AsmPositionalAfter { span, named, explicit });
-            }
+            dcx.emit_err(errors::AsmPositionalAfter { span, named, explicit });
         }
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index d770da5a8c4..f2ae9f9c8a6 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -48,6 +48,10 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
     fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation) {
         self.location = Some(dbg_loc);
     }
+
+    fn clear_dbg_loc(&mut self) {
+        self.location = None;
+    }
 }
 
 /// Generate the `debug_context` in an MIR Body.
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 09896b89ebf..2ebe0be53aa 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -92,11 +92,9 @@ fn prepare_lto(
                     dcx.emit_err(LtoDylib);
                     return Err(FatalError);
                 }
-            } else if *crate_type == CrateType::ProcMacro {
-                if !cgcx.opts.unstable_opts.dylib_lto {
-                    dcx.emit_err(LtoProcMacro);
-                    return Err(FatalError);
-                }
+            } else if *crate_type == CrateType::ProcMacro && !cgcx.opts.unstable_opts.dylib_lto {
+                dcx.emit_err(LtoProcMacro);
+                return Err(FatalError);
             }
         }
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 01aae24ab56..73c2c15717f 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -27,7 +27,7 @@ use rustc_span::source_map::Spanned;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{HasDataLayout, TargetDataLayout, VariantIdx};
-use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
+use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
 use smallvec::SmallVec;
 
 use crate::back::write::to_llvm_code_model;
@@ -387,6 +387,24 @@ pub(crate) unsafe fn create_module<'ll>(
         }
     }
 
+    match (sess.opts.unstable_opts.small_data_threshold, sess.target.small_data_threshold_support())
+    {
+        // Set up the small-data optimization limit for architectures that use
+        // an LLVM module flag to control this.
+        (Some(threshold), SmallDataThresholdSupport::LlvmModuleFlag(flag)) => {
+            let flag = SmallCStr::new(flag.as_ref());
+            unsafe {
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Error,
+                    flag.as_c_str().as_ptr(),
+                    threshold as u32,
+                )
+            }
+        }
+        _ => (),
+    };
+
     // Insert `llvm.ident` metadata.
     //
     // On the wasm targets it will get hooked up to the "producer" sections
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index f5d6fc6f080..842212ac05d 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -1,8 +1,8 @@
 #![doc = include_str!("doc.md")]
 
 use std::cell::{OnceCell, RefCell};
-use std::iter;
 use std::ops::Range;
+use std::{iter, ptr};
 
 use libc::c_uint;
 use rustc_codegen_ssa::debuginfo::type_names;
@@ -209,6 +209,12 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
         }
     }
 
+    fn clear_dbg_loc(&mut self) {
+        unsafe {
+            llvm::LLVMSetCurrentDebugLocation2(self.llbuilder, ptr::null());
+        }
+    }
+
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
         gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 3bf4d496408..e84ab0aa538 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1041,7 +1041,7 @@ unsafe extern "C" {
     pub fn LLVMDisposeBuilder<'a>(Builder: &'a mut Builder<'a>);
 
     // Metadata
-    pub fn LLVMSetCurrentDebugLocation2<'a>(Builder: &Builder<'a>, Loc: &'a Metadata);
+    pub fn LLVMSetCurrentDebugLocation2<'a>(Builder: &Builder<'a>, Loc: *const Metadata);
 
     // Terminators
     pub fn LLVMBuildRetVoid<'a>(B: &Builder<'a>) -> &'a Value;
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 6e4ddbb6f3b..29afe6f6bfc 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -14,7 +14,7 @@ use rustc_middle::bug;
 use rustc_session::config::{PrintKind, PrintRequest};
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
-use rustc_target::spec::{MergeFunctions, PanicStrategy};
+use rustc_target::spec::{MergeFunctions, PanicStrategy, SmallDataThresholdSupport};
 use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATURES};
 
 use crate::back::write::create_informational_target_machine;
@@ -125,6 +125,18 @@ unsafe fn configure_llvm(sess: &Session) {
         for arg in sess_args {
             add(&(*arg), true);
         }
+
+        match (
+            sess.opts.unstable_opts.small_data_threshold,
+            sess.target.small_data_threshold_support(),
+        ) {
+            // Set up the small-data optimization limit for architectures that use
+            // an LLVM argument to control this.
+            (Some(threshold), SmallDataThresholdSupport::LlvmArg(arg)) => {
+                add(&format!("--{arg}={threshold}"), false)
+            }
+            _ => (),
+        };
     }
 
     if sess.opts.unstable_opts.llvm_time_trace {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index dbb65707bd2..40eb35deea5 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -281,12 +281,10 @@ pub fn each_linked_rlib(
         let used_crate_source = &info.used_crate_source[&cnum];
         if let Some((path, _)) = &used_crate_source.rlib {
             f(cnum, path);
+        } else if used_crate_source.rmeta.is_some() {
+            return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
         } else {
-            if used_crate_source.rmeta.is_some() {
-                return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
-            } else {
-                return Err(errors::LinkRlibError::NotFound { crate_name });
-            }
+            return Err(errors::LinkRlibError::NotFound { crate_name });
         }
     }
     Ok(())
@@ -628,12 +626,10 @@ fn link_staticlib(
         let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
         if let Some((path, _)) = &used_crate_source.dylib {
             all_rust_dylibs.push(&**path);
+        } else if used_crate_source.rmeta.is_some() {
+            sess.dcx().emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
         } else {
-            if used_crate_source.rmeta.is_some() {
-                sess.dcx().emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
-            } else {
-                sess.dcx().emit_fatal(errors::LinkRlibError::NotFound { crate_name });
-            }
+            sess.dcx().emit_fatal(errors::LinkRlibError::NotFound { crate_name });
         }
     }
 
@@ -1972,10 +1968,8 @@ fn add_late_link_args(
         if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) {
             cmd.verbatim_args(args.iter().map(Deref::deref));
         }
-    } else {
-        if let Some(args) = sess.target.late_link_args_static.get(&flavor) {
-            cmd.verbatim_args(args.iter().map(Deref::deref));
-        }
+    } else if let Some(args) = sess.target.late_link_args_static.get(&flavor) {
+        cmd.verbatim_args(args.iter().map(Deref::deref));
     }
     if let Some(args) = sess.target.late_link_args.get(&flavor) {
         cmd.verbatim_args(args.iter().map(Deref::deref));
@@ -2635,10 +2629,8 @@ fn add_native_libs_from_crate(
                     if link_static {
                         cmd.link_staticlib_by_name(name, verbatim, false);
                     }
-                } else {
-                    if link_dynamic {
-                        cmd.link_dylib_by_name(name, verbatim, true);
-                    }
+                } else if link_dynamic {
+                    cmd.link_dylib_by_name(name, verbatim, true);
                 }
             }
             NativeLibKind::Framework { as_needed } => {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index ea71b92de3a..7f5f9f03868 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -791,14 +791,12 @@ impl<'a> Linker for GccLinker<'a> {
             self.link_arg("-exported_symbols_list").link_arg(path);
         } else if self.sess.target.is_like_solaris {
             self.link_arg("-M").link_arg(path);
+        } else if is_windows {
+            self.link_arg(path);
         } else {
-            if is_windows {
-                self.link_arg(path);
-            } else {
-                let mut arg = OsString::from("--version-script=");
-                arg.push(path);
-                self.link_arg(arg).link_arg("--no-undefined-version");
-            }
+            let mut arg = OsString::from("--version-script=");
+            arg.push(path);
+            self.link_arg(arg).link_arg("--no-undefined-version");
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 4ab20c154cc..9149c602296 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -617,32 +617,29 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     // purpose functions as they wouldn't have the right target features
     // enabled. For that reason we also forbid #[inline(always)] as it can't be
     // respected.
-    if !codegen_fn_attrs.target_features.is_empty() {
-        if codegen_fn_attrs.inline == InlineAttr::Always {
-            if let Some(span) = inline_span {
-                tcx.dcx().span_err(
-                    span,
-                    "cannot use `#[inline(always)]` with \
+    if !codegen_fn_attrs.target_features.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always
+    {
+        if let Some(span) = inline_span {
+            tcx.dcx().span_err(
+                span,
+                "cannot use `#[inline(always)]` with \
                      `#[target_feature]`",
-                );
-            }
+            );
         }
     }
 
-    if !codegen_fn_attrs.no_sanitize.is_empty() {
-        if codegen_fn_attrs.inline == InlineAttr::Always {
-            if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
-                let hir_id = tcx.local_def_id_to_hir_id(did);
-                tcx.node_span_lint(
-                    lint::builtin::INLINE_NO_SANITIZE,
-                    hir_id,
-                    no_sanitize_span,
-                    |lint| {
-                        lint.primary_message("`no_sanitize` will have no effect after inlining");
-                        lint.span_note(inline_span, "inlining requested here");
-                    },
-                )
-            }
+    if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
+        if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
+            let hir_id = tcx.local_def_id_to_hir_id(did);
+            tcx.node_span_lint(
+                lint::builtin::INLINE_NO_SANITIZE,
+                hir_id,
+                no_sanitize_span,
+                |lint| {
+                    lint.primary_message("`no_sanitize` will have no effect after inlining");
+                    lint.span_note(inline_span, "inlining requested here");
+                },
+            )
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 5103b2f3158..e34fbfe3f76 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -236,15 +236,13 @@ fn push_debuginfo_type_name<'tcx>(
             let has_enclosing_parens = if cpp_like_debuginfo {
                 output.push_str("dyn$<");
                 false
+            } else if trait_data.len() > 1 && auto_traits.len() != 0 {
+                // We need enclosing parens because there is more than one trait
+                output.push_str("(dyn ");
+                true
             } else {
-                if trait_data.len() > 1 && auto_traits.len() != 0 {
-                    // We need enclosing parens because there is more than one trait
-                    output.push_str("(dyn ");
-                    true
-                } else {
-                    output.push_str("dyn ");
-                    false
-                }
+                output.push_str("dyn ");
+                false
             };
 
             if let Some(principal) = trait_data.principal() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 75692540c03..ab08ef72a69 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -547,6 +547,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         self.set_debug_loc(bx, var.source_info);
                         let base =
                             Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
+                        bx.clear_dbg_loc();
 
                         bx.dbg_var_addr(
                             dbg_var,
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 31104e5749b..5fbe97214fb 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -80,6 +80,7 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
         fragment: Option<Range<Size>>,
     );
     fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
+    fn clear_dbg_loc(&mut self);
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
     fn set_var_name(&mut self, value: Self::Value, name: &str);
 }
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 594b98f34ef..337eab7a1c2 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -73,12 +73,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
 
     // This can't use `init_stack_frame` since `body` is not a function,
     // so computing its ABI would fail. It's also not worth it since there are no arguments to pass.
-    ecx.push_stack_frame_raw(
-        cid.instance,
-        body,
-        &ret.clone().into(),
-        StackPopCleanup::Root { cleanup: false },
-    )?;
+    ecx.push_stack_frame_raw(cid.instance, body, &ret, StackPopCleanup::Root { cleanup: false })?;
     ecx.storage_live_for_always_live_locals()?;
 
     // The main interpreter loop.
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 419d412b063..0f2b22f035b 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -823,7 +823,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             (Abi::Rust, fn_abi),
             &[FnArg::Copy(arg.into())],
             false,
-            &ret.into(),
+            &ret,
             Some(target),
             unwind,
         )
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index dd744c51f23..16d40fcceb6 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -16,7 +16,7 @@ use rustc_span::Span;
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};
 use rustc_trait_selection::traits::ObligationCtxt;
-use tracing::{debug, trace};
+use tracing::{debug, instrument, trace};
 
 use super::{
     err_inval, throw_inval, throw_ub, throw_ub_custom, Frame, FrameInfo, GlobalId, InterpErrorInfo,
@@ -315,6 +315,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Check if the two things are equal in the current param_env, using an infctx to get proper
     /// equality checks.
+    #[instrument(level = "trace", skip(self), ret)]
     pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
     where
         T: PartialEq + TypeFoldable<TyCtxt<'tcx>> + ToTrace<'tcx>,
@@ -330,13 +331,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         // equate the two trait refs after normalization
         let a = ocx.normalize(&cause, self.param_env, a);
         let b = ocx.normalize(&cause, self.param_env, b);
-        if ocx.eq(&cause, self.param_env, a, b).is_ok() {
-            if ocx.select_all_or_error().is_empty() {
-                // All good.
-                return true;
-            }
+
+        if let Err(terr) = ocx.eq(&cause, self.param_env, a, b) {
+            trace!(?terr);
+            return false;
+        }
+
+        let errors = ocx.select_all_or_error();
+        if !errors.is_empty() {
+            trace!(?errors);
+            return false;
         }
-        return false;
+
+        // All good.
+        true
     }
 
     /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index bedc56de0da..8a07f90c951 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -384,8 +384,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             sym::simd_insert => {
                 let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
                 let elem = &args[2];
-                let (input, input_len) = self.operand_to_simd(&args[0])?;
-                let (dest, dest_len) = self.mplace_to_simd(dest)?;
+                let (input, input_len) = self.project_to_simd(&args[0])?;
+                let (dest, dest_len) = self.project_to_simd(dest)?;
                 assert_eq!(input_len, dest_len, "Return vector length must match input length");
                 // Bounds are not checked by typeck so we have to do it ourselves.
                 if index >= input_len {
@@ -406,7 +406,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             }
             sym::simd_extract => {
                 let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
-                let (input, input_len) = self.operand_to_simd(&args[0])?;
+                let (input, input_len) = self.project_to_simd(&args[0])?;
                 // Bounds are not checked by typeck so we have to do it ourselves.
                 if index >= input_len {
                     throw_ub_format!(
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index bb7e58b83ac..2e02d1001c8 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -681,30 +681,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         Ok(str)
     }
 
-    /// Converts a repr(simd) operand into an operand where `place_index` accesses the SIMD elements.
-    /// Also returns the number of elements.
-    ///
-    /// Can (but does not always) trigger UB if `op` is uninitialized.
-    pub fn operand_to_simd(
-        &self,
-        op: &OpTy<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> {
-        // Basically we just transmute this place into an array following simd_size_and_type.
-        // This only works in memory, but repr(simd) types should never be immediates anyway.
-        assert!(op.layout.ty.is_simd());
-        match op.as_mplace_or_imm() {
-            Left(mplace) => self.mplace_to_simd(&mplace),
-            Right(imm) => match *imm {
-                Immediate::Uninit => {
-                    throw_ub!(InvalidUninitBytes(None))
-                }
-                Immediate::Scalar(..) | Immediate::ScalarPair(..) => {
-                    bug!("arrays/slices can never have Scalar/ScalarPair layout")
-                }
-            },
-        }
-    }
-
     /// Read from a local of the current frame.
     /// Will not access memory, instead an indirect `Operand` is returned.
     ///
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 1eca92812df..9dd9ca80385 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -377,13 +377,15 @@ where
     Prov: Provenance,
     M: Machine<'tcx, Provenance = Prov>,
 {
-    pub fn ptr_with_meta_to_mplace(
+    fn ptr_with_meta_to_mplace(
         &self,
         ptr: Pointer<Option<M::Provenance>>,
         meta: MemPlaceMeta<M::Provenance>,
         layout: TyAndLayout<'tcx>,
+        unaligned: bool,
     ) -> MPlaceTy<'tcx, M::Provenance> {
-        let misaligned = self.is_ptr_misaligned(ptr, layout.align.abi);
+        let misaligned =
+            if unaligned { None } else { self.is_ptr_misaligned(ptr, layout.align.abi) };
         MPlaceTy { mplace: MemPlace { ptr, meta, misaligned }, layout }
     }
 
@@ -393,7 +395,16 @@ where
         layout: TyAndLayout<'tcx>,
     ) -> MPlaceTy<'tcx, M::Provenance> {
         assert!(layout.is_sized());
-        self.ptr_with_meta_to_mplace(ptr, MemPlaceMeta::None, layout)
+        self.ptr_with_meta_to_mplace(ptr, MemPlaceMeta::None, layout, /*unaligned*/ false)
+    }
+
+    pub fn ptr_to_mplace_unaligned(
+        &self,
+        ptr: Pointer<Option<M::Provenance>>,
+        layout: TyAndLayout<'tcx>,
+    ) -> MPlaceTy<'tcx, M::Provenance> {
+        assert!(layout.is_sized());
+        self.ptr_with_meta_to_mplace(ptr, MemPlaceMeta::None, layout, /*unaligned*/ true)
     }
 
     /// Take a value, which represents a (thin or wide) reference, and make it a place.
@@ -414,7 +425,7 @@ where
         // `ref_to_mplace` is called on raw pointers even if they don't actually get dereferenced;
         // we hence can't call `size_and_align_of` since that asserts more validity than we want.
         let ptr = ptr.to_pointer(self)?;
-        Ok(self.ptr_with_meta_to_mplace(ptr, meta, layout))
+        Ok(self.ptr_with_meta_to_mplace(ptr, meta, layout, /*unaligned*/ false))
     }
 
     /// Turn a mplace into a (thin or wide) mutable raw pointer, pointing to the same space.
@@ -484,23 +495,6 @@ where
         Ok(a)
     }
 
-    /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
-    /// Also returns the number of elements.
-    pub fn mplace_to_simd(
-        &self,
-        mplace: &MPlaceTy<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> {
-        // Basically we want to transmute this place into an array following simd_size_and_type.
-        let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx);
-        // Some SIMD types have padding, so `len` many `e_ty` does not cover the entire place.
-        // Therefore we cannot transmute, and instead we project at offset 0, which side-steps
-        // the size check.
-        let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, e_ty, len))?;
-        assert!(array_layout.size <= mplace.layout.size);
-        let mplace = mplace.offset(Size::ZERO, array_layout, self)?;
-        Ok((mplace, len))
-    }
-
     /// Turn a local in the current frame into a place.
     pub fn local_to_place(
         &self,
@@ -986,7 +980,7 @@ where
             span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known")
         };
         let ptr = self.allocate_ptr(size, align, kind)?;
-        Ok(self.ptr_with_meta_to_mplace(ptr.into(), meta, layout))
+        Ok(self.ptr_with_meta_to_mplace(ptr.into(), meta, layout, /*unaligned*/ false))
     }
 
     pub fn allocate(
@@ -1021,7 +1015,12 @@ where
         };
         let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self);
         let layout = self.layout_of(self.tcx.types.str_).unwrap();
-        Ok(self.ptr_with_meta_to_mplace(ptr.into(), MemPlaceMeta::Meta(meta), layout))
+        Ok(self.ptr_with_meta_to_mplace(
+            ptr.into(),
+            MemPlaceMeta::Meta(meta),
+            layout,
+            /*unaligned*/ false,
+        ))
     }
 
     pub fn raw_const_to_mplace(
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index dd8dd21e0e8..641ed5bb7c0 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -244,6 +244,19 @@ where
         base.offset(offset, field_layout, self)
     }
 
+    /// Converts a repr(simd) value into an array of the right size, such that `project_index`
+    /// accesses the SIMD elements. Also returns the number of elements.
+    pub fn project_to_simd<P: Projectable<'tcx, M::Provenance>>(
+        &self,
+        base: &P,
+    ) -> InterpResult<'tcx, (P, u64)> {
+        assert!(base.layout().ty.ty_adt_def().unwrap().repr().simd());
+        // SIMD types must be newtypes around arrays, so all we have to do is project to their only field.
+        let array = self.project_field(base, 0)?;
+        let len = array.len(self)?;
+        Ok((array, len))
+    }
+
     fn project_constant_index<P: Projectable<'tcx, M::Provenance>>(
         &self,
         base: &P,
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 6f5bcebbbb6..490355f416c 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::{
 };
 use tracing::debug;
 
-use super::{throw_inval, InterpCx, MPlaceTy, MemPlaceMeta, MemoryKind};
+use super::{throw_inval, InterpCx, MPlaceTy, MemoryKind};
 use crate::const_eval::{CompileTimeInterpCx, CompileTimeMachine, InterpretationResult};
 
 /// Checks whether a type contains generic parameters which must be instantiated.
@@ -103,5 +103,5 @@ pub(crate) fn create_static_alloc<'tcx>(
     assert_eq!(ecx.machine.static_root_ids, None);
     ecx.machine.static_root_ids = Some((alloc_id, static_def_id));
     assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none());
-    Ok(ecx.ptr_with_meta_to_mplace(Pointer::from(alloc_id).into(), MemPlaceMeta::None, layout))
+    Ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout))
 }
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index c973fcec0e1..74225d646bd 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -222,10 +222,8 @@ impl<'tcx> PrintExtra<'tcx> {
 }
 
 pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
-    if ppm.needs_analysis() {
-        if ex.tcx().analysis(()).is_err() {
-            FatalError.raise();
-        }
+    if ppm.needs_analysis() && ex.tcx().analysis(()).is_err() {
+        FatalError.raise();
     }
 
     let (src, src_name) = get_source(sess);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 412a2c17081..7a4d8dba179 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -681,10 +681,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
             " ".repeat(expected_padding),
             expected_label
         ))];
-        msg.extend(expected.0.into_iter());
+        msg.extend(expected.0);
         msg.push(StringPart::normal(format!("`{expected_extra}\n")));
         msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
-        msg.extend(found.0.into_iter());
+        msg.extend(found.0);
         msg.push(StringPart::normal(format!("`{found_extra}")));
 
         // For now, just attach these as notes.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 3254dab9a03..6ed5ea9f8bb 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -193,8 +193,6 @@ declare_features! (
     (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
     /// Allows identifying the `compiler_builtins` crate.
     (internal, compiler_builtins, "1.13.0", None),
-    /// Gating for a new desugaring of const arguments of usages of const parameters
-    (internal, const_arg_path, "1.81.0", None),
     /// Allows writing custom MIR
     (internal, custom_mir, "1.65.0", None),
     /// Outputs useful `assert!` messages
@@ -497,6 +495,8 @@ declare_features! (
     (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)),
     /// Allows `if let` guard in match arms.
     (unstable, if_let_guard, "1.47.0", Some(51114)),
+    /// Rescoping temporaries in `if let` to align with Rust 2024.
+    (unstable, if_let_rescope, "CURRENT_RUSTC_VERSION", Some(124085)),
     /// Allows `impl Trait` to be used inside associated types (RFC 2515).
     (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)),
     /// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index d7b2510a1df..1d686878eab 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1151,42 +1151,40 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
                 "type has conflicting packed and align representation hints"
             )
             .emit();
-        } else {
-            if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) {
-                let mut err = struct_span_code_err!(
-                    tcx.dcx(),
-                    sp,
-                    E0588,
-                    "packed type cannot transitively contain a `#[repr(align)]` type"
-                );
+        } else if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) {
+            let mut err = struct_span_code_err!(
+                tcx.dcx(),
+                sp,
+                E0588,
+                "packed type cannot transitively contain a `#[repr(align)]` type"
+            );
 
-                err.span_note(
-                    tcx.def_span(def_spans[0].0),
-                    format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)),
-                );
+            err.span_note(
+                tcx.def_span(def_spans[0].0),
+                format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)),
+            );
 
-                if def_spans.len() > 2 {
-                    let mut first = true;
-                    for (adt_def, span) in def_spans.iter().skip(1).rev() {
-                        let ident = tcx.item_name(*adt_def);
-                        err.span_note(
-                            *span,
-                            if first {
-                                format!(
-                                    "`{}` contains a field of type `{}`",
-                                    tcx.type_of(def.did()).instantiate_identity(),
-                                    ident
-                                )
-                            } else {
-                                format!("...which contains a field of type `{ident}`")
-                            },
-                        );
-                        first = false;
-                    }
+            if def_spans.len() > 2 {
+                let mut first = true;
+                for (adt_def, span) in def_spans.iter().skip(1).rev() {
+                    let ident = tcx.item_name(*adt_def);
+                    err.span_note(
+                        *span,
+                        if first {
+                            format!(
+                                "`{}` contains a field of type `{}`",
+                                tcx.type_of(def.did()).instantiate_identity(),
+                                ident
+                            )
+                        } else {
+                            format!("...which contains a field of type `{ident}`")
+                        },
+                    );
+                    first = false;
                 }
-
-                err.emit();
             }
+
+            err.emit();
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 6820a44f141..dbdad2eb41d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -186,17 +186,15 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
 
     if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
         && alloc.inner().provenance().ptrs().len() != 0
-    {
-        if attrs
+        && attrs
             .link_section
             .map(|link_section| !link_section.as_str().starts_with(".init_array"))
             .unwrap()
-        {
-            let msg = "statics with a custom `#[link_section]` must be a \
+    {
+        let msg = "statics with a custom `#[link_section]` must be a \
                         simple list of bytes on the wasm target with no \
                         extra levels of indirection such as references";
-            tcx.dcx().span_err(tcx.def_span(id), msg);
-        }
+        tcx.dcx().span_err(tcx.def_span(id), msg);
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 2d6147cff2a..33e58a92e37 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -472,7 +472,12 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
 
         hir::ExprKind::If(cond, then, Some(otherwise)) => {
             let expr_cx = visitor.cx;
-            visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen });
+            let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope {
+                ScopeData::IfThenRescope
+            } else {
+                ScopeData::IfThen
+            };
+            visitor.enter_scope(Scope { id: then.hir_id.local_id, data });
             visitor.cx.var_parent = visitor.cx.parent;
             visitor.visit_expr(cond);
             visitor.visit_expr(then);
@@ -482,7 +487,12 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
 
         hir::ExprKind::If(cond, then, None) => {
             let expr_cx = visitor.cx;
-            visitor.enter_scope(Scope { id: then.hir_id.local_id, data: ScopeData::IfThen });
+            let data = if expr.span.at_least_rust_2024() && visitor.tcx.features().if_let_rescope {
+                ScopeData::IfThenRescope
+            } else {
+                ScopeData::IfThen
+            };
+            visitor.enter_scope(Scope { id: then.hir_id.local_id, data });
             visitor.cx.var_parent = visitor.cx.parent;
             visitor.visit_expr(cond);
             visitor.visit_expr(then);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3627faf8dfc..10b3fe380ab 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1602,7 +1602,7 @@ fn check_fn_or_method<'tcx>(
                     function: def_id,
                     // Note that the `param_idx` of the output type is
                     // one greater than the index of the last input type.
-                    param_idx: idx.try_into().unwrap(),
+                    param_idx: idx,
                 }),
                 ty,
             )
@@ -1611,7 +1611,7 @@ fn check_fn_or_method<'tcx>(
     for (idx, ty) in sig.inputs_and_output.iter().enumerate() {
         wfcx.register_wf_obligation(
             arg_span(idx),
-            Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
+            Some(WellFormedLoc::Param { function: def_id, param_idx: idx }),
             ty.into(),
         );
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index db809e4837d..f2a97d06771 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -53,17 +53,15 @@ fn enforce_trait_manually_implementable(
 ) -> Result<(), ErrorGuaranteed> {
     let impl_header_span = tcx.def_span(impl_def_id);
 
-    if tcx.is_lang_item(trait_def_id, LangItem::Freeze) {
-        if !tcx.features().freeze_impls {
-            feature_err(
-                &tcx.sess,
-                sym::freeze_impls,
-                impl_header_span,
-                "explicit impls for the `Freeze` trait are not permitted",
-            )
-            .with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
-            .emit();
-        }
+    if tcx.is_lang_item(trait_def_id, LangItem::Freeze) && !tcx.features().freeze_impls {
+        feature_err(
+            &tcx.sess,
+            sym::freeze_impls,
+            impl_header_span,
+            "explicit impls for the `Freeze` trait are not permitted",
+        )
+        .with_span_label(impl_header_span, format!("impl of `Freeze` not allowed"))
+        .emit();
     }
 
     // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]`
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 7f4a8208faa..2afb29abd68 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -381,24 +381,22 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
         }
 
         mir_opaque_ty.ty
+    } else if let Some(guar) = tables.tainted_by_errors {
+        // Some error in the owner fn prevented us from populating
+        // the `concrete_opaque_types` table.
+        Ty::new_error(tcx, guar)
     } else {
-        if let Some(guar) = tables.tainted_by_errors {
-            // Some error in the owner fn prevented us from populating
-            // the `concrete_opaque_types` table.
-            Ty::new_error(tcx, guar)
+        // Fall back to the RPIT we inferred during HIR typeck
+        if let Some(hir_opaque_ty) = hir_opaque_ty {
+            hir_opaque_ty.ty
         } else {
-            // Fall back to the RPIT we inferred during HIR typeck
-            if let Some(hir_opaque_ty) = hir_opaque_ty {
-                hir_opaque_ty.ty
-            } else {
-                // We failed to resolve the opaque type or it
-                // resolves to itself. We interpret this as the
-                // no values of the hidden type ever being constructed,
-                // so we can just make the hidden type be `!`.
-                // For backwards compatibility reasons, we fall back to
-                // `()` until we the diverging default is changed.
-                Ty::new_diverging_default(tcx)
-            }
+            // We failed to resolve the opaque type or it
+            // resolves to itself. We interpret this as the
+            // no values of the hidden type ever being constructed,
+            // so we can just make the hidden type be `!`.
+            // For backwards compatibility reasons, we fall back to
+            // `()` until we the diverging default is changed.
+            Ty::new_diverging_default(tcx)
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
index da89f5769d1..97402dd1109 100644
--- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
@@ -827,20 +827,18 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
 
             if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args
                 == num_trait_generics_except_self
+                && let Some(span) = self.gen_args.span_ext()
+                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
             {
-                if let Some(span) = self.gen_args.span_ext()
-                    && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
-                {
-                    let sugg = vec![
-                        (
-                            self.path_segment.ident.span,
-                            format!("{}::{}", snippet, self.path_segment.ident),
-                        ),
-                        (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
-                    ];
+                let sugg = vec![
+                    (
+                        self.path_segment.ident.span,
+                        format!("{}::{}", snippet, self.path_segment.ident),
+                    ),
+                    (span.with_lo(self.path_segment.ident.span.hi()), "".to_owned()),
+                ];
 
-                    err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
-                }
+                err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index ac5bd825b18..7163352e8a4 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -562,13 +562,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, preceding_args)
                                 .into()
+                        } else if infer_args {
+                            self.lowerer.ct_infer(Some(param), self.span).into()
                         } else {
-                            if infer_args {
-                                self.lowerer.ct_infer(Some(param), self.span).into()
-                            } else {
-                                // We've already errored above about the mismatch.
-                                ty::Const::new_misc_error(tcx).into()
-                            }
+                            // We've already errored above about the mismatch.
+                            ty::Const::new_misc_error(tcx).into()
                         }
                     }
                 }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 9863d036449..3dc8759a9ed 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -58,7 +58,7 @@ pub(crate) fn check_legal_trait_for_method_call(
 enum CallStep<'tcx> {
     Builtin(Ty<'tcx>),
     DeferredClosure(LocalDefId, ty::FnSig<'tcx>),
-    /// E.g., enum variant constructors.
+    /// Call overloading when callee implements one of the Fn* traits.
     Overloaded(MethodCallee<'tcx>),
 }
 
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 1e1e007862e..36892aaf80c 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -732,12 +732,11 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             }
             _ => return Err(CastError::NonScalar),
         };
-        if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
-            if adt_def.did().krate != LOCAL_CRATE {
-                if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
-                    return Err(CastError::ForeignNonExhaustiveAdt);
-                }
-            }
+        if let ty::Adt(adt_def, _) = *self.expr_ty.kind()
+            && adt_def.did().krate != LOCAL_CRATE
+            && adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive)
+        {
+            return Err(CastError::ForeignNonExhaustiveAdt);
         }
         match (t_from, t_cast) {
             // These types have invariants! can't cast into them.
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 80a179fce03..6fd509ed32f 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1780,16 +1780,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // Make sure the programmer specified correct number of fields.
-        if adt_kind == AdtKind::Union {
-            if hir_fields.len() != 1 {
-                struct_span_code_err!(
-                    self.dcx(),
-                    span,
-                    E0784,
-                    "union expressions should have exactly one field",
-                )
-                .emit();
-            }
+        if adt_kind == AdtKind::Union && hir_fields.len() != 1 {
+            struct_span_code_err!(
+                self.dcx(),
+                span,
+                E0784,
+                "union expressions should have exactly one field",
+            )
+            .emit();
         }
 
         // If check_expr_struct_fields hit an error, do not attempt to populate
@@ -2904,21 +2902,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     candidate_fields.iter().map(|path| format!("{unwrap}{path}")),
                     Applicability::MaybeIncorrect,
                 );
-            } else {
-                if let Some(field_name) = find_best_match_for_name(&field_names, field.name, None) {
-                    err.span_suggestion_verbose(
-                        field.span,
-                        "a field with a similar name exists",
-                        format!("{unwrap}{}", field_name),
-                        Applicability::MaybeIncorrect,
-                    );
-                } else if !field_names.is_empty() {
-                    let is = if field_names.len() == 1 { " is" } else { "s are" };
-                    err.note(format!(
-                        "available field{is}: {}",
-                        self.name_series_display(field_names),
-                    ));
-                }
+            } else if let Some(field_name) =
+                find_best_match_for_name(&field_names, field.name, None)
+            {
+                err.span_suggestion_verbose(
+                    field.span,
+                    "a field with a similar name exists",
+                    format!("{unwrap}{}", field_name),
+                    Applicability::MaybeIncorrect,
+                );
+            } else if !field_names.is_empty() {
+                let is = if field_names.len() == 1 { " is" } else { "s are" };
+                err.note(
+                    format!("available field{is}: {}", self.name_series_display(field_names),),
+                );
             }
         }
         err
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 15e3ba4ffc2..8348c6e9a16 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -506,6 +506,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 fn_def_id,
                 call_span,
                 call_expr,
+                tuple_arguments,
             );
         }
     }
@@ -520,6 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fn_def_id: Option<DefId>,
         call_span: Span,
         call_expr: &'tcx hir::Expr<'tcx>,
+        tuple_arguments: TupleArgumentsFlag,
     ) -> ErrorGuaranteed {
         // Next, let's construct the error
         let (error_span, call_ident, full_call_span, call_name, is_method) = match &call_expr.kind {
@@ -865,6 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         &matched_inputs,
                         &formal_and_expected_inputs,
                         is_method,
+                        tuple_arguments,
                     );
                     suggest_confusable(&mut err);
                     return err.emit();
@@ -1001,6 +1004,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 &matched_inputs,
                 &formal_and_expected_inputs,
                 is_method,
+                tuple_arguments,
             );
             suggest_confusable(&mut err);
             return err.emit();
@@ -1448,6 +1452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             &matched_inputs,
             &formal_and_expected_inputs,
             is_method,
+            tuple_arguments,
         );
 
         // And add a suggestion block for all of the parameters
@@ -2219,21 +2224,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         matched_inputs: &IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
         formal_and_expected_inputs: &IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
         is_method: bool,
+        tuple_arguments: TupleArgumentsFlag,
     ) {
         let Some(mut def_id) = callable_def_id else {
             return;
         };
 
+        // If we're calling a method of a Fn/FnMut/FnOnce trait object implicitly
+        // (eg invoking a closure) we want to point at the underlying callable,
+        // not the method implicitly invoked (eg call_once).
         if let Some(assoc_item) = self.tcx.opt_associated_item(def_id)
-            // Possibly points at either impl or trait item, so try to get it
-            // to point to trait item, then get the parent.
-            // This parent might be an impl in the case of an inherent function,
-            // but the next check will fail.
+            // Since this is an associated item, it might point at either an impl or a trait item.
+            // We want it to always point to the trait item.
+            // If we're pointing at an inherent function, we don't need to do anything,
+            // so we fetch the parent and verify if it's a trait item.
             && let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
             && let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
             // Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
             && let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id)
             && let Some(callee_ty) = callee_ty
+            // TupleArguments is set only when this is an implicit call (my_closure(...)) rather than explicit (my_closure.call(...))
+            && tuple_arguments == TupleArguments
         {
             let callee_ty = callee_ty.peel_refs();
             match *callee_ty.kind() {
@@ -2303,166 +2314,173 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let mut spans: MultiSpan = def_span.into();
 
-            let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
-            let mut generics_with_unmatched_params = Vec::new();
+            if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method)
+            {
+                debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
 
-            let check_for_matched_generics = || {
-                if matched_inputs.iter().any(|x| x.is_some())
-                    && params_with_generics.iter().any(|x| x.0.is_some())
-                {
-                    for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
-                        // Param has to have a generic and be matched to be relevant
-                        if matched_inputs[idx.into()].is_none() {
-                            continue;
-                        }
+                let mut generics_with_unmatched_params = Vec::new();
 
-                        let Some(generic) = generic else {
-                            continue;
-                        };
+                let check_for_matched_generics = || {
+                    if matched_inputs.iter().any(|x| x.is_some())
+                        && params_with_generics.iter().any(|x| x.0.is_some())
+                    {
+                        for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
+                            // Param has to have a generic and be matched to be relevant
+                            if matched_inputs[idx.into()].is_none() {
+                                continue;
+                            }
 
-                        for unmatching_idx in idx + 1..params_with_generics.len() {
-                            if matched_inputs[unmatching_idx.into()].is_none()
-                                && let Some(unmatched_idx_param_generic) =
-                                    params_with_generics[unmatching_idx].0
-                                && unmatched_idx_param_generic.name.ident() == generic.name.ident()
-                            {
-                                // We found a parameter that didn't match that needed to
-                                return true;
+                            let Some(generic) = generic else {
+                                continue;
+                            };
+
+                            for unmatching_idx in idx + 1..params_with_generics.len() {
+                                if matched_inputs[unmatching_idx.into()].is_none()
+                                    && let Some(unmatched_idx_param_generic) =
+                                        params_with_generics[unmatching_idx].0
+                                    && unmatched_idx_param_generic.name.ident()
+                                        == generic.name.ident()
+                                {
+                                    // We found a parameter that didn't match that needed to
+                                    return true;
+                                }
                             }
                         }
                     }
-                }
-                false
-            };
-
-            let check_for_matched_generics = check_for_matched_generics();
-
-            for (idx, (generic_param, param)) in
-                params_with_generics.iter().enumerate().filter(|(idx, _)| {
-                    check_for_matched_generics
-                        || expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
-                })
-            {
-                let Some(generic_param) = generic_param else {
-                    spans.push_span_label(param.span, "");
-                    continue;
+                    false
                 };
 
-                let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
-                    .iter()
-                    .enumerate()
-                    .filter(|(other_idx, (other_generic_param, _))| {
-                        if *other_idx == idx {
-                            return false;
-                        }
-                        let Some(other_generic_param) = other_generic_param else {
-                            return false;
-                        };
-                        if matched_inputs[idx.into()].is_none()
-                            && matched_inputs[(*other_idx).into()].is_none()
-                        {
-                            return false;
-                        }
-                        if matched_inputs[idx.into()].is_some()
-                            && matched_inputs[(*other_idx).into()].is_some()
-                        {
-                            return false;
-                        }
-                        other_generic_param.name.ident() == generic_param.name.ident()
+                let check_for_matched_generics = check_for_matched_generics();
+
+                for (idx, (generic_param, param)) in
+                    params_with_generics.iter().enumerate().filter(|(idx, _)| {
+                        check_for_matched_generics
+                            || expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
                     })
-                    .map(|(other_idx, (_, other_param))| (other_idx, *other_param))
-                    .collect();
+                {
+                    let Some(generic_param) = generic_param else {
+                        spans.push_span_label(param.span, "");
+                        continue;
+                    };
 
-                if !other_params_matched.is_empty() {
-                    let other_param_matched_names: Vec<String> = other_params_matched
+                    let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
                         .iter()
-                        .map(|(_, other_param)| {
-                            if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind {
-                                format!("`{ident}`")
-                            } else {
-                                "{unknown}".to_string()
+                        .enumerate()
+                        .filter(|(other_idx, (other_generic_param, _))| {
+                            if *other_idx == idx {
+                                return false;
+                            }
+                            let Some(other_generic_param) = other_generic_param else {
+                                return false;
+                            };
+                            if matched_inputs[idx.into()].is_none()
+                                && matched_inputs[(*other_idx).into()].is_none()
+                            {
+                                return false;
                             }
+                            if matched_inputs[idx.into()].is_some()
+                                && matched_inputs[(*other_idx).into()].is_some()
+                            {
+                                return false;
+                            }
+                            other_generic_param.name.ident() == generic_param.name.ident()
                         })
+                        .map(|(other_idx, (_, other_param))| (other_idx, *other_param))
                         .collect();
 
-                    let matched_ty = self
-                        .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
-                        .sort_string(self.tcx);
+                    if !other_params_matched.is_empty() {
+                        let other_param_matched_names: Vec<String> = other_params_matched
+                            .iter()
+                            .map(|(_, other_param)| {
+                                if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind
+                                {
+                                    format!("`{ident}`")
+                                } else {
+                                    "{unknown}".to_string()
+                                }
+                            })
+                            .collect();
 
-                    if matched_inputs[idx.into()].is_some() {
-                        spans.push_span_label(
-                            param.span,
-                            format!(
-                                "{} {} to match the {} type of this parameter",
-                                display_list_with_comma_and(&other_param_matched_names),
+                        let matched_ty = self
+                            .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                            .sort_string(self.tcx);
+
+                        if matched_inputs[idx.into()].is_some() {
+                            spans.push_span_label(
+                                param.span,
                                 format!(
-                                    "need{}",
-                                    pluralize!(if other_param_matched_names.len() == 1 {
-                                        0
-                                    } else {
-                                        1
-                                    })
+                                    "{} {} to match the {} type of this parameter",
+                                    display_list_with_comma_and(&other_param_matched_names),
+                                    format!(
+                                        "need{}",
+                                        pluralize!(if other_param_matched_names.len() == 1 {
+                                            0
+                                        } else {
+                                            1
+                                        })
+                                    ),
+                                    matched_ty,
                                 ),
-                                matched_ty,
-                            ),
-                        );
+                            );
+                        } else {
+                            spans.push_span_label(
+                                param.span,
+                                format!(
+                                    "this parameter needs to match the {} type of {}",
+                                    matched_ty,
+                                    display_list_with_comma_and(&other_param_matched_names),
+                                ),
+                            );
+                        }
+                        generics_with_unmatched_params.push(generic_param);
                     } else {
+                        spans.push_span_label(param.span, "");
+                    }
+                }
+
+                for generic_param in self
+                    .tcx
+                    .hir()
+                    .get_if_local(def_id)
+                    .and_then(|node| node.generics())
+                    .into_iter()
+                    .flat_map(|x| x.params)
+                    .filter(|x| {
+                        generics_with_unmatched_params
+                            .iter()
+                            .any(|y| x.name.ident() == y.name.ident())
+                    })
+                {
+                    let param_idents_matching: Vec<String> = params_with_generics
+                        .iter()
+                        .filter(|(generic, _)| {
+                            if let Some(generic) = generic {
+                                generic.name.ident() == generic_param.name.ident()
+                            } else {
+                                false
+                            }
+                        })
+                        .map(|(_, param)| {
+                            if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
+                                format!("`{ident}`")
+                            } else {
+                                "{unknown}".to_string()
+                            }
+                        })
+                        .collect();
+
+                    if !param_idents_matching.is_empty() {
                         spans.push_span_label(
-                            param.span,
+                            generic_param.span,
                             format!(
-                                "this parameter needs to match the {} type of {}",
-                                matched_ty,
-                                display_list_with_comma_and(&other_param_matched_names),
+                                "{} all reference this parameter {}",
+                                display_list_with_comma_and(&param_idents_matching),
+                                generic_param.name.ident().name,
                             ),
                         );
                     }
-                    generics_with_unmatched_params.push(generic_param);
-                } else {
-                    spans.push_span_label(param.span, "");
                 }
             }
-
-            for generic_param in self
-                .tcx
-                .hir()
-                .get_if_local(def_id)
-                .and_then(|node| node.generics())
-                .into_iter()
-                .flat_map(|x| x.params)
-                .filter(|x| {
-                    generics_with_unmatched_params.iter().any(|y| x.name.ident() == y.name.ident())
-                })
-            {
-                let param_idents_matching: Vec<String> = params_with_generics
-                    .iter()
-                    .filter(|(generic, _)| {
-                        if let Some(generic) = generic {
-                            generic.name.ident() == generic_param.name.ident()
-                        } else {
-                            false
-                        }
-                    })
-                    .map(|(_, param)| {
-                        if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
-                            format!("`{ident}`")
-                        } else {
-                            "{unknown}".to_string()
-                        }
-                    })
-                    .collect();
-
-                if !param_idents_matching.is_empty() {
-                    spans.push_span_label(
-                        generic_param.span,
-                        format!(
-                            "{} all reference this parameter {}",
-                            display_list_with_comma_and(&param_idents_matching),
-                            generic_param.name.ident().name,
-                        ),
-                    );
-                }
-            }
-
             err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id)));
         } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id)
             && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind
@@ -2535,74 +2553,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         };
 
-        let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
-
-        for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
-            if matched_inputs[idx.into()].is_none() {
-                continue;
-            }
+        if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) {
+            debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
+            for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
+                if matched_inputs[idx.into()].is_none() {
+                    continue;
+                }
 
-            let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
-                continue;
-            };
+                let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
+                    continue;
+                };
 
-            let Some(generic_param) = generic_param else {
-                continue;
-            };
+                let Some(generic_param) = generic_param else {
+                    continue;
+                };
 
-            let mut idxs_matched: Vec<usize> = vec![];
-            for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
-                |(other_idx, (other_generic_param, _))| {
-                    if *other_idx == idx {
-                        return false;
-                    }
-                    let Some(other_generic_param) = other_generic_param else {
-                        return false;
-                    };
-                    if matched_inputs[(*other_idx).into()].is_some() {
-                        return false;
-                    }
-                    other_generic_param.name.ident() == generic_param.name.ident()
-                },
-            ) {
-                idxs_matched.push(other_idx.into());
-            }
+                let mut idxs_matched: Vec<usize> = vec![];
+                for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
+                    |(other_idx, (other_generic_param, _))| {
+                        if *other_idx == idx {
+                            return false;
+                        }
+                        let Some(other_generic_param) = other_generic_param else {
+                            return false;
+                        };
+                        if matched_inputs[(*other_idx).into()].is_some() {
+                            return false;
+                        }
+                        other_generic_param.name.ident() == generic_param.name.ident()
+                    },
+                ) {
+                    idxs_matched.push(other_idx);
+                }
 
-            if idxs_matched.is_empty() {
-                continue;
-            }
+                if idxs_matched.is_empty() {
+                    continue;
+                }
 
-            let expected_display_type = self
-                .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
-                .sort_string(self.tcx);
-            let label = if idxs_matched.len() == params_with_generics.len() - 1 {
-                format!(
-                    "expected all arguments to be this {} type because they need to match the type of this parameter",
-                    expected_display_type
-                )
-            } else {
-                format!(
-                    "expected some other arguments to be {} {} type to match the type of this parameter",
-                    a_or_an(&expected_display_type),
-                    expected_display_type,
-                )
-            };
+                let expected_display_type = self
+                    .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                    .sort_string(self.tcx);
+                let label = if idxs_matched.len() == params_with_generics.len() - 1 {
+                    format!(
+                        "expected all arguments to be this {} type because they need to match the type of this parameter",
+                        expected_display_type
+                    )
+                } else {
+                    format!(
+                        "expected some other arguments to be {} {} type to match the type of this parameter",
+                        a_or_an(&expected_display_type),
+                        expected_display_type,
+                    )
+                };
 
-            err.span_label(*matched_arg_span, label);
+                err.span_label(*matched_arg_span, label);
+            }
         }
     }
 
+    /// Returns the parameters of a function, with their generic parameters if those are the full
+    /// type of that parameter. Returns `None` if the function body is unavailable (eg is an instrinsic).
     fn get_hir_params_with_generics(
         &self,
         def_id: DefId,
         is_method: bool,
-    ) -> Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)> {
-        let fn_node = self.tcx.hir().get_if_local(def_id);
+    ) -> Option<Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
+        let fn_node = self.tcx.hir().get_if_local(def_id)?;
 
         let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_node
-            .and_then(|node| node.fn_decl())
+            .fn_decl()?
+            .inputs
             .into_iter()
-            .flat_map(|decl| decl.inputs)
             .skip(if is_method { 1 } else { 0 })
             .map(|param| {
                 if let hir::TyKind::Path(QPath::Resolved(
@@ -2611,7 +2632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 )) = param.kind
                 {
                     fn_node
-                        .and_then(|node| node.generics())
+                        .generics()
                         .into_iter()
                         .flat_map(|generics| generics.params)
                         .find(|param| &param.def_id.to_def_id() == res_def_id)
@@ -2621,14 +2642,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             })
             .collect();
 
-        let params: Vec<&hir::Param<'_>> = fn_node
-            .and_then(|node| node.body_id())
+        let params: Vec<&hir::Param<'_>> = self
+            .tcx
+            .hir()
+            .body(fn_node.body_id()?)
+            .params
             .into_iter()
-            .flat_map(|id| self.tcx.hir().body(id).params)
             .skip(if is_method { 1 } else { 0 })
             .collect();
 
-        generic_params.into_iter().zip(params).collect()
+        Some(generic_params.into_iter().zip_eq(params).collect())
     }
 }
 
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index 4ea22884cf3..2f990de7e31 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -158,14 +158,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
                         ),
                     );
                 }
-            } else {
-                if !self.fcx.tcx.features().unsized_locals {
-                    self.fcx.require_type_is_sized(
-                        var_ty,
-                        p.span,
-                        ObligationCauseCode::VariableType(p.hir_id),
-                    );
-                }
+            } else if !self.fcx.tcx.features().unsized_locals {
+                self.fcx.require_type_is_sized(
+                    var_ty,
+                    p.span,
+                    ObligationCauseCode::VariableType(p.hir_id),
+                );
             }
 
             debug!(
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 178d5dce086..9ede809ead2 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1252,11 +1252,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             && suggested_bounds.contains(parent)
                         {
                             // We don't suggest `PartialEq` when we already suggest `Eq`.
-                        } else if !suggested_bounds.contains(pred) {
-                            if collect_type_param_suggestions(self_ty, *pred, &p) {
-                                suggested = true;
-                                suggested_bounds.insert(pred);
-                            }
+                        } else if !suggested_bounds.contains(pred)
+                            && collect_type_param_suggestions(self_ty, *pred, &p)
+                        {
+                            suggested = true;
+                            suggested_bounds.insert(pred);
                         }
                         (
                             match parent_pred {
@@ -1267,14 +1267,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         if !suggested
                                             && !suggested_bounds.contains(pred)
                                             && !suggested_bounds.contains(parent_pred)
-                                        {
-                                            if collect_type_param_suggestions(
+                                            && collect_type_param_suggestions(
                                                 self_ty,
                                                 *parent_pred,
                                                 &p,
-                                            ) {
-                                                suggested_bounds.insert(pred);
-                                            }
+                                            )
+                                        {
+                                            suggested_bounds.insert(pred);
                                         }
                                         format!("`{p}`\nwhich is required by `{parent_p}`")
                                     }
diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs
index 88cb82f0f37..cef0b23143d 100644
--- a/compiler/rustc_incremental/src/persist/dirty_clean.rs
+++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs
@@ -417,12 +417,10 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
 fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
     if let Some(value) = item.value_str() {
         value
+    } else if let Some(ident) = item.ident() {
+        tcx.dcx().emit_fatal(errors::AssociatedValueExpectedFor { span: item.span(), ident });
     } else {
-        if let Some(ident) = item.ident() {
-            tcx.dcx().emit_fatal(errors::AssociatedValueExpectedFor { span: item.span(), ident });
-        } else {
-            tcx.dcx().emit_fatal(errors::AssociatedValueExpected { span: item.span() });
-        }
+        tcx.dcx().emit_fatal(errors::AssociatedValueExpected { span: item.span() });
     }
 }
 
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 50422df8ee6..080f2a1785a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -808,7 +808,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(mir_opt_level, Some(4));
     tracked!(move_size_limit, Some(4096));
     tracked!(mutable_noalias, false);
-    tracked!(next_solver, NextSolverConfig { coherence: true, globally: true });
+    tracked!(next_solver, Some(NextSolverConfig { coherence: true, globally: false }));
     tracked!(no_generate_arange_section, true);
     tracked!(no_jump_tables, true);
     tracked!(no_link, true);
@@ -847,6 +847,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(share_generics, Some(true));
     tracked!(show_span, Some(String::from("abc")));
     tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
+    tracked!(small_data_threshold, Some(16));
     tracked!(split_lto_unit, Some(true));
     tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1));
     tracked!(stack_protector, StackProtector::All);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 7d4dee45c26..4aa86944a0b 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -334,6 +334,11 @@ lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len ->
         *[other] {" "}{$identifier_type}
     } Unicode general security profile
 
+lint_if_let_rescope = `if let` assigns a shorter lifetime since Edition 2024
+    .label = this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
+    .help = the value is now dropped here in Edition 2024
+    .suggestion = a `match` with a single arm can preserve the drop order up to Edition 2021
+
 lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level
 
 lint_ill_formed_attribute_input = {$num_suggestions ->
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 7de92a43a9a..8b92180e9bd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -429,10 +429,8 @@ impl MissingDoc {
         // Only check publicly-visible items, using the result from the privacy pass.
         // It's an option so the crate root can also use this function (it doesn't
         // have a `NodeId`).
-        if def_id != CRATE_DEF_ID {
-            if !cx.effective_visibilities.is_exported(def_id) {
-                return;
-            }
+        if def_id != CRATE_DEF_ID && !cx.effective_visibilities.is_exported(def_id) {
+            return;
         }
 
         let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id));
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index a60fc0ffbbb..33b8b7c544b 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -3,8 +3,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_middle::query::Providers;
-use rustc_middle::ty::layout::LayoutError;
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtDef, Instance, Ty, TyCtxt};
 use rustc_session::declare_lint;
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::FIRST_VARIANT;
@@ -212,7 +211,17 @@ fn structurally_same_type<'tcx>(
     ckind: types::CItemKind,
 ) -> bool {
     let mut seen_types = UnordSet::default();
-    structurally_same_type_impl(&mut seen_types, tcx, param_env, a, b, ckind)
+    let result = structurally_same_type_impl(&mut seen_types, tcx, param_env, a, b, ckind);
+    if cfg!(debug_assertions) && result {
+        // Sanity-check: must have same ABI, size and alignment.
+        // `extern` blocks cannot be generic, so we'll always get a layout here.
+        let a_layout = tcx.layout_of(param_env.and(a)).unwrap();
+        let b_layout = tcx.layout_of(param_env.and(b)).unwrap();
+        assert_eq!(a_layout.abi, b_layout.abi);
+        assert_eq!(a_layout.size, b_layout.size);
+        assert_eq!(a_layout.align, b_layout.align);
+    }
+    result
 }
 
 fn structurally_same_type_impl<'tcx>(
@@ -266,30 +275,21 @@ fn structurally_same_type_impl<'tcx>(
         // Do a full, depth-first comparison between the two.
         use rustc_type_ir::TyKind::*;
 
-        let compare_layouts = |a, b| -> Result<bool, &'tcx LayoutError<'tcx>> {
-            debug!("compare_layouts({:?}, {:?})", a, b);
-            let a_layout = &tcx.layout_of(param_env.and(a))?.layout.abi();
-            let b_layout = &tcx.layout_of(param_env.and(b))?.layout.abi();
-            debug!(
-                "comparing layouts: {:?} == {:?} = {}",
-                a_layout,
-                b_layout,
-                a_layout == b_layout
-            );
-            Ok(a_layout == b_layout)
-        };
-
         let is_primitive_or_pointer =
             |ty: Ty<'tcx>| ty.is_primitive() || matches!(ty.kind(), RawPtr(..) | Ref(..));
 
         ensure_sufficient_stack(|| {
             match (a.kind(), b.kind()) {
-                (Adt(a_def, _), Adt(b_def, _)) => {
-                    // We can immediately rule out these types as structurally same if
-                    // their layouts differ.
-                    match compare_layouts(a, b) {
-                        Ok(false) => return false,
-                        _ => (), // otherwise, continue onto the full, fields comparison
+                (&Adt(a_def, _), &Adt(b_def, _)) => {
+                    // Only `repr(C)` types can be compared structurally.
+                    if !(a_def.repr().c() && b_def.repr().c()) {
+                        return false;
+                    }
+                    // If the types differ in their packed-ness, align, or simd-ness they conflict.
+                    let repr_characteristica =
+                        |def: AdtDef<'tcx>| (def.repr().pack, def.repr().align, def.repr().simd());
+                    if repr_characteristica(a_def) != repr_characteristica(b_def) {
+                        return false;
                     }
 
                     // Grab a flattened representation of all fields.
@@ -311,9 +311,9 @@ fn structurally_same_type_impl<'tcx>(
                         },
                     )
                 }
-                (Array(a_ty, a_const), Array(b_ty, b_const)) => {
-                    // For arrays, we also check the constness of the type.
-                    a_const.kind() == b_const.kind()
+                (Array(a_ty, a_len), Array(b_ty, b_len)) => {
+                    // For arrays, we also check the length.
+                    a_len == b_len
                         && structurally_same_type_impl(
                             seen_types, tcx, param_env, *a_ty, *b_ty, ckind,
                         )
@@ -357,10 +357,9 @@ fn structurally_same_type_impl<'tcx>(
                             ckind,
                         )
                 }
-                (Tuple(a_args), Tuple(b_args)) => {
-                    a_args.iter().eq_by(b_args.iter(), |a_ty, b_ty| {
-                        structurally_same_type_impl(seen_types, tcx, param_env, a_ty, b_ty, ckind)
-                    })
+                (Tuple(..), Tuple(..)) => {
+                    // Tuples are not `repr(C)` so these cannot be compared structurally.
+                    false
                 }
                 // For these, it's not quite as easy to define structural-sameness quite so easily.
                 // For the purposes of this lint, take the conservative approach and mark them as
@@ -380,24 +379,21 @@ fn structurally_same_type_impl<'tcx>(
                 // An Adt and a primitive or pointer type. This can be FFI-safe if non-null
                 // enum layout optimisation is being applied.
                 (Adt(..), _) if is_primitive_or_pointer(b) => {
-                    if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
-                        ty == b
+                    if let Some(a_inner) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
+                        a_inner == b
                     } else {
-                        compare_layouts(a, b).unwrap_or(false)
+                        false
                     }
                 }
                 (_, Adt(..)) if is_primitive_or_pointer(a) => {
-                    if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
-                        ty == a
+                    if let Some(b_inner) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
+                        b_inner == a
                     } else {
-                        compare_layouts(a, b).unwrap_or(false)
+                        false
                     }
                 }
 
-                // Otherwise, just compare the layouts. This may fail to lint for some
-                // incompatible types, but at the very least, will stop reads into
-                // uninitialised memory.
-                _ => compare_layouts(a, b).unwrap_or(false),
+                _ => false,
             }
         })
     }
diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs
new file mode 100644
index 00000000000..5b65541bea6
--- /dev/null
+++ b/compiler/rustc_lint/src/if_let_rescope.rs
@@ -0,0 +1,430 @@
+use std::iter::repeat;
+use std::ops::ControlFlow;
+
+use hir::intravisit::Visitor;
+use rustc_ast::Recovered;
+use rustc_errors::{
+    Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
+};
+use rustc_hir::{self as hir, HirIdSet};
+use rustc_macros::LintDiagnostic;
+use rustc_middle::ty::TyCtxt;
+use rustc_session::lint::{FutureIncompatibilityReason, Level};
+use rustc_session::{declare_lint, impl_lint_pass};
+use rustc_span::edition::Edition;
+use rustc_span::Span;
+
+use crate::{LateContext, LateLintPass};
+
+declare_lint! {
+    /// The `if_let_rescope` lint detects cases where a temporary value with
+    /// significant drop is generated on the right hand side of `if let`
+    /// and suggests a rewrite into `match` when possible.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,edition2021
+    /// #![feature(if_let_rescope)]
+    /// #![warn(if_let_rescope)]
+    /// #![allow(unused_variables)]
+    ///
+    /// struct Droppy;
+    /// impl Drop for Droppy {
+    ///     fn drop(&mut self) {
+    ///         // Custom destructor, including this `drop` implementation, is considered
+    ///         // significant.
+    ///         // Rust does not check whether this destructor emits side-effects that can
+    ///         // lead to observable change in program semantics, when the drop order changes.
+    ///         // Rust biases to be on the safe side, so that you can apply discretion whether
+    ///         // this change indeed breaches any contract or specification that your code needs
+    ///         // to honour.
+    ///         println!("dropped");
+    ///     }
+    /// }
+    /// impl Droppy {
+    ///     fn get(&self) -> Option<u8> {
+    ///         None
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     if let Some(value) = Droppy.get() {
+    ///         // do something
+    ///     } else {
+    ///         // do something else
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// With Edition 2024, temporaries generated while evaluating `if let`s
+    /// will be dropped before the `else` block.
+    /// This lint captures a possible change in runtime behaviour due to
+    /// a change in sequence of calls to significant `Drop::drop` destructors.
+    ///
+    /// A significant [`Drop::drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html)
+    /// destructor here refers to an explicit, arbitrary implementation of the `Drop` trait on the type
+    /// with exceptions including `Vec`, `Box`, `Rc`, `BTreeMap` and `HashMap`
+    /// that are marked by the compiler otherwise so long that the generic types have
+    /// no significant destructor recursively.
+    /// In other words, a type has a significant drop destructor when it has a `Drop` implementation
+    /// or its destructor invokes a significant destructor on a type.
+    /// Since we cannot completely reason about the change by just inspecting the existence of
+    /// a significant destructor, this lint remains only a suggestion and is set to `allow` by default.
+    ///
+    /// Whenever possible, a rewrite into an equivalent `match` expression that
+    /// observe the same order of calls to such destructors is proposed by this lint.
+    /// Authors may take their own discretion whether the rewrite suggestion shall be
+    /// accepted, or rejected to continue the use of the `if let` expression.
+    pub IF_LET_RESCOPE,
+    Allow,
+    "`if let` assigns a shorter lifetime to temporary values being pattern-matched against in Edition 2024 and \
+    rewriting in `match` is an option to preserve the semantics up to Edition 2021",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
+        reference: "issue #124085 <https://github.com/rust-lang/rust/issues/124085>",
+    };
+}
+
+/// Lint for potential change in program semantics of `if let`s
+#[derive(Default)]
+pub(crate) struct IfLetRescope {
+    skip: HirIdSet,
+}
+
+fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
+    let Some((_, hir::Node::Expr(expr))) = tcx.hir().parent_iter(hir_id).next() else {
+        return false;
+    };
+    let hir::ExprKind::If(_cond, _conseq, Some(alt)) = expr.kind else { return false };
+    alt.hir_id == hir_id
+}
+
+fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
+    let Some((_, hir::Node::Stmt(stmt))) = tcx.hir().parent_iter(hir_id).next() else {
+        return false;
+    };
+    let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = stmt.kind else { return false };
+    expr.hir_id == hir_id
+}
+
+fn match_head_needs_bracket(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> bool {
+    expr_parent_is_else(tcx, expr.hir_id) && matches!(expr.kind, hir::ExprKind::If(..))
+}
+
+impl IfLetRescope {
+    fn probe_if_cascade<'tcx>(&mut self, cx: &LateContext<'tcx>, mut expr: &'tcx hir::Expr<'tcx>) {
+        if self.skip.contains(&expr.hir_id) {
+            return;
+        }
+        let tcx = cx.tcx;
+        let source_map = tcx.sess.source_map();
+        let expr_end = expr.span.shrink_to_hi();
+        let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr);
+        let mut significant_droppers = vec![];
+        let mut lifetime_ends = vec![];
+        let mut closing_brackets = 0;
+        let mut alt_heads = vec![];
+        let mut match_heads = vec![];
+        let mut consequent_heads = vec![];
+        let mut first_if_to_lint = None;
+        let mut first_if_to_rewrite = false;
+        let mut empty_alt = false;
+        while let hir::ExprKind::If(cond, conseq, alt) = expr.kind {
+            self.skip.insert(expr.hir_id);
+            // We are interested in `let` fragment of the condition.
+            // Otherwise, we probe into the `else` fragment.
+            if let hir::ExprKind::Let(&hir::LetExpr {
+                span,
+                pat,
+                init,
+                ty: ty_ascription,
+                recovered: Recovered::No,
+            }) = cond.kind
+            {
+                let if_let_pat = expr.span.shrink_to_lo().between(init.span);
+                // The consequent fragment is always a block.
+                let before_conseq = conseq.span.shrink_to_lo();
+                let lifetime_end = source_map.end_point(conseq.span);
+
+                if let ControlFlow::Break(significant_dropper) =
+                    (FindSignificantDropper { cx }).visit_expr(init)
+                {
+                    first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id)));
+                    significant_droppers.push(significant_dropper);
+                    lifetime_ends.push(lifetime_end);
+                    if ty_ascription.is_some()
+                        || !expr.span.can_be_used_for_suggestions()
+                        || !pat.span.can_be_used_for_suggestions()
+                    {
+                        // Our `match` rewrites does not support type ascription,
+                        // so we just bail.
+                        // Alternatively when the span comes from proc macro expansion,
+                        // we will also bail.
+                        // FIXME(#101728): change this when type ascription syntax is stabilized again
+                    } else if let Ok(pat) = source_map.span_to_snippet(pat.span) {
+                        let emit_suggestion = |alt_span| {
+                            first_if_to_rewrite = true;
+                            if add_bracket_to_match_head {
+                                closing_brackets += 2;
+                                match_heads.push(SingleArmMatchBegin::WithOpenBracket(if_let_pat));
+                            } else {
+                                // Sometimes, wrapping `match` into a block is undesirable,
+                                // because the scrutinee temporary lifetime is shortened and
+                                // the proposed fix will not work.
+                                closing_brackets += 1;
+                                match_heads
+                                    .push(SingleArmMatchBegin::WithoutOpenBracket(if_let_pat));
+                            }
+                            consequent_heads.push(ConsequentRewrite { span: before_conseq, pat });
+                            if let Some(alt_span) = alt_span {
+                                alt_heads.push(AltHead(alt_span));
+                            }
+                        };
+                        if let Some(alt) = alt {
+                            let alt_head = conseq.span.between(alt.span);
+                            if alt_head.can_be_used_for_suggestions() {
+                                // We lint only when the `else` span is user code, too.
+                                emit_suggestion(Some(alt_head));
+                            }
+                        } else {
+                            // This is the end of the `if .. else ..` cascade.
+                            // We can stop here.
+                            emit_suggestion(None);
+                            empty_alt = true;
+                            break;
+                        }
+                    }
+                }
+            }
+            // At this point, any `if let` fragment in the cascade is definitely preceeded by `else`,
+            // so a opening bracket is mandatory before each `match`.
+            add_bracket_to_match_head = true;
+            if let Some(alt) = alt {
+                expr = alt;
+            } else {
+                break;
+            }
+        }
+        if let Some((span, hir_id)) = first_if_to_lint {
+            tcx.emit_node_span_lint(
+                IF_LET_RESCOPE,
+                hir_id,
+                span,
+                IfLetRescopeLint {
+                    significant_droppers,
+                    lifetime_ends,
+                    rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite {
+                        match_heads,
+                        consequent_heads,
+                        closing_brackets: ClosingBrackets {
+                            span: expr_end,
+                            count: closing_brackets,
+                            empty_alt,
+                        },
+                        alt_heads,
+                    }),
+                },
+            );
+        }
+    }
+}
+
+impl_lint_pass!(
+    IfLetRescope => [IF_LET_RESCOPE]
+);
+
+impl<'tcx> LateLintPass<'tcx> for IfLetRescope {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
+        if expr.span.edition().at_least_rust_2024() || !cx.tcx.features().if_let_rescope {
+            return;
+        }
+        if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) {
+            return;
+        }
+        if expr_parent_is_stmt(cx.tcx, expr.hir_id)
+            && matches!(expr.kind, hir::ExprKind::If(_cond, _conseq, None))
+        {
+            // `if let` statement without an `else` branch has no observable change
+            // so we can skip linting it
+            return;
+        }
+        self.probe_if_cascade(cx, expr);
+    }
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_if_let_rescope)]
+struct IfLetRescopeLint {
+    #[label]
+    significant_droppers: Vec<Span>,
+    #[help]
+    lifetime_ends: Vec<Span>,
+    #[subdiagnostic]
+    rewrite: Option<IfLetRescopeRewrite>,
+}
+
+// #[derive(Subdiagnostic)]
+struct IfLetRescopeRewrite {
+    match_heads: Vec<SingleArmMatchBegin>,
+    consequent_heads: Vec<ConsequentRewrite>,
+    closing_brackets: ClosingBrackets,
+    alt_heads: Vec<AltHead>,
+}
+
+impl Subdiagnostic for IfLetRescopeRewrite {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        f: &F,
+    ) {
+        let mut suggestions = vec![];
+        for match_head in self.match_heads {
+            match match_head {
+                SingleArmMatchBegin::WithOpenBracket(span) => {
+                    suggestions.push((span, "{ match ".into()))
+                }
+                SingleArmMatchBegin::WithoutOpenBracket(span) => {
+                    suggestions.push((span, "match ".into()))
+                }
+            }
+        }
+        for ConsequentRewrite { span, pat } in self.consequent_heads {
+            suggestions.push((span, format!("{{ {pat} => ")));
+        }
+        for AltHead(span) in self.alt_heads {
+            suggestions.push((span, " _ => ".into()));
+        }
+        let closing_brackets = self.closing_brackets;
+        suggestions.push((
+            closing_brackets.span,
+            closing_brackets
+                .empty_alt
+                .then_some(" _ => {}".chars())
+                .into_iter()
+                .flatten()
+                .chain(repeat('}').take(closing_brackets.count))
+                .collect(),
+        ));
+        let msg = f(diag, crate::fluent_generated::lint_suggestion.into());
+        diag.multipart_suggestion_with_style(
+            msg,
+            suggestions,
+            Applicability::MachineApplicable,
+            SuggestionStyle::ShowCode,
+        );
+    }
+}
+
+struct AltHead(Span);
+
+struct ConsequentRewrite {
+    span: Span,
+    pat: String,
+}
+
+struct ClosingBrackets {
+    span: Span,
+    count: usize,
+    empty_alt: bool,
+}
+enum SingleArmMatchBegin {
+    WithOpenBracket(Span),
+    WithoutOpenBracket(Span),
+}
+
+struct FindSignificantDropper<'tcx, 'a> {
+    cx: &'a LateContext<'tcx>,
+}
+
+impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
+    type Result = ControlFlow<Span>;
+
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
+        if self
+            .cx
+            .typeck_results()
+            .expr_ty(expr)
+            .has_significant_drop(self.cx.tcx, self.cx.param_env)
+        {
+            return ControlFlow::Break(expr.span);
+        }
+        match expr.kind {
+            hir::ExprKind::ConstBlock(_)
+            | hir::ExprKind::Lit(_)
+            | hir::ExprKind::Path(_)
+            | hir::ExprKind::Assign(_, _, _)
+            | hir::ExprKind::AssignOp(_, _, _)
+            | hir::ExprKind::Break(_, _)
+            | hir::ExprKind::Continue(_)
+            | hir::ExprKind::Ret(_)
+            | hir::ExprKind::Become(_)
+            | hir::ExprKind::InlineAsm(_)
+            | hir::ExprKind::OffsetOf(_, _)
+            | hir::ExprKind::Repeat(_, _)
+            | hir::ExprKind::Err(_)
+            | hir::ExprKind::Struct(_, _, _)
+            | hir::ExprKind::Closure(_)
+            | hir::ExprKind::Block(_, _)
+            | hir::ExprKind::DropTemps(_)
+            | hir::ExprKind::Loop(_, _, _, _) => ControlFlow::Continue(()),
+
+            hir::ExprKind::Tup(exprs) | hir::ExprKind::Array(exprs) => {
+                for expr in exprs {
+                    self.visit_expr(expr)?;
+                }
+                ControlFlow::Continue(())
+            }
+            hir::ExprKind::Call(callee, args) => {
+                self.visit_expr(callee)?;
+                for expr in args {
+                    self.visit_expr(expr)?;
+                }
+                ControlFlow::Continue(())
+            }
+            hir::ExprKind::MethodCall(_, receiver, args, _) => {
+                self.visit_expr(receiver)?;
+                for expr in args {
+                    self.visit_expr(expr)?;
+                }
+                ControlFlow::Continue(())
+            }
+            hir::ExprKind::Index(left, right, _) | hir::ExprKind::Binary(_, left, right) => {
+                self.visit_expr(left)?;
+                self.visit_expr(right)
+            }
+            hir::ExprKind::Unary(_, expr)
+            | hir::ExprKind::Cast(expr, _)
+            | hir::ExprKind::Type(expr, _)
+            | hir::ExprKind::Yield(expr, _)
+            | hir::ExprKind::AddrOf(_, _, expr)
+            | hir::ExprKind::Match(expr, _, _)
+            | hir::ExprKind::Field(expr, _)
+            | hir::ExprKind::Let(&hir::LetExpr {
+                init: expr,
+                span: _,
+                pat: _,
+                ty: _,
+                recovered: Recovered::No,
+            }) => self.visit_expr(expr),
+            hir::ExprKind::Let(_) => ControlFlow::Continue(()),
+
+            hir::ExprKind::If(cond, _, _) => {
+                if let hir::ExprKind::Let(hir::LetExpr {
+                    init,
+                    span: _,
+                    pat: _,
+                    ty: _,
+                    recovered: Recovered::No,
+                }) = cond.kind
+                {
+                    self.visit_expr(init)?;
+                }
+                ControlFlow::Continue(())
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 4139ac4e3e9..5c67e21687f 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -56,6 +56,7 @@ mod expect;
 mod for_loops_over_fallibles;
 mod foreign_modules;
 pub mod hidden_unicode_codepoints;
+mod if_let_rescope;
 mod impl_trait_overcaptures;
 mod internal;
 mod invalid_from_utf8;
@@ -94,6 +95,7 @@ use drop_forget_useless::*;
 use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
 use for_loops_over_fallibles::*;
 use hidden_unicode_codepoints::*;
+use if_let_rescope::IfLetRescope;
 use impl_trait_overcaptures::ImplTraitOvercaptures;
 use internal::*;
 use invalid_from_utf8::*;
@@ -243,6 +245,7 @@ late_lint_methods!(
             NonLocalDefinitions: NonLocalDefinitions::default(),
             ImplTraitOvercaptures: ImplTraitOvercaptures,
             TailExprDropOrder: TailExprDropOrder,
+            IfLetRescope: IfLetRescope::default(),
         ]
     ]
 );
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 6ef1801717c..999743ed73b 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -96,6 +96,7 @@ impl fmt::Debug for Scope {
             ScopeData::Arguments => write!(fmt, "Arguments({:?})", self.id),
             ScopeData::Destruction => write!(fmt, "Destruction({:?})", self.id),
             ScopeData::IfThen => write!(fmt, "IfThen({:?})", self.id),
+            ScopeData::IfThenRescope => write!(fmt, "IfThen[edition2024]({:?})", self.id),
             ScopeData::Remainder(fsi) => write!(
                 fmt,
                 "Remainder {{ block: {:?}, first_statement_index: {}}}",
@@ -126,6 +127,11 @@ pub enum ScopeData {
     /// Used for variables introduced in an if-let expression.
     IfThen,
 
+    /// Scope of the condition and then block of an if expression
+    /// Used for variables introduced in an if-let expression,
+    /// whose lifetimes do not cross beyond this scope.
+    IfThenRescope,
+
     /// Scope following a `let id = expr;` binding in a block.
     Remainder(FirstStatementIndex),
 }
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 3b8861378e0..86dca27f04f 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -444,10 +444,11 @@ impl<'tcx> TyCtxt<'tcx> {
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
-                if feature == sym::rustc_private && issue == NonZero::new(27812) {
-                    if self.sess.opts.unstable_opts.force_unstable_if_unmarked {
-                        return EvalResult::Allow;
-                    }
+                if feature == sym::rustc_private
+                    && issue == NonZero::new(27812)
+                    && self.sess.opts.unstable_opts.force_unstable_if_unmarked
+                {
+                    return EvalResult::Allow;
                 }
 
                 if matches!(allow_unstable, AllowUnstable::Yes) {
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index fc38f27137e..4c5da188860 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -448,22 +448,20 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
                 bad: uninit_range,
             }))
         })?;
-        if !Prov::OFFSET_IS_ADDR {
-            if !self.provenance.range_empty(range, cx) {
-                // Find the provenance.
-                let (offset, _prov) = self
-                    .provenance
-                    .range_get_ptrs(range, cx)
-                    .first()
-                    .copied()
-                    .expect("there must be provenance somewhere here");
-                let start = offset.max(range.start); // the pointer might begin before `range`!
-                let end = (offset + cx.pointer_size()).min(range.end()); // the pointer might end after `range`!
-                return Err(AllocError::ReadPointerAsInt(Some(BadBytesAccess {
-                    access: range,
-                    bad: AllocRange::from(start..end),
-                })));
-            }
+        if !Prov::OFFSET_IS_ADDR && !self.provenance.range_empty(range, cx) {
+            // Find the provenance.
+            let (offset, _prov) = self
+                .provenance
+                .range_get_ptrs(range, cx)
+                .first()
+                .copied()
+                .expect("there must be provenance somewhere here");
+            let start = offset.max(range.start); // the pointer might begin before `range`!
+            let end = (offset + cx.pointer_size()).min(range.end()); // the pointer might end after `range`!
+            return Err(AllocError::ReadPointerAsInt(Some(BadBytesAccess {
+                access: range,
+                bad: AllocRange::from(start..end),
+            })));
         }
         Ok(self.get_bytes_unchecked(range))
     }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 26addb1e357..e312e65cc21 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1084,6 +1084,9 @@ pub enum LocalInfo<'tcx> {
     /// (with no intervening statement context).
     // FIXME(matthewjasper) Don't store in this in `Body`
     BlockTailTemp(BlockTailInfo),
+    /// A temporary created during evaluating `if` predicate, possibly for pattern matching for `let`s,
+    /// and subject to Edition 2024 temporary lifetime rules
+    IfThenRescopeTemp { if_then: HirId },
     /// A temporary created during the pass `Derefer` to avoid it's retagging
     DerefTemp,
     /// A temporary created for borrow checking.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a98e6943d68..d66d0be1009 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -208,12 +208,10 @@ fn dump_path<'tcx>(
 
     let pass_num = if tcx.sess.opts.unstable_opts.dump_mir_exclude_pass_number {
         String::new()
+    } else if pass_num {
+        format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count)
     } else {
-        if pass_num {
-            format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count)
-        } else {
-            ".-------".to_string()
-        }
+        ".-------".to_string()
     };
 
     let crate_name = tcx.crate_name(source.def_id().krate);
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 362ff8e988d..6708ae60562 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -295,20 +295,12 @@ impl<'tcx> Const<'tcx> {
             _ => expr,
         };
 
-        if let hir::ExprKind::Path(
-            qpath @ hir::QPath::Resolved(
-                _,
-                &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
-            ),
-        ) = expr.kind
+        if let hir::ExprKind::Path(hir::QPath::Resolved(
+            _,
+            &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
+        )) = expr.kind
         {
-            if tcx.features().const_arg_path {
-                span_bug!(
-                    expr.span,
-                    "try_from_lit: received const param which shouldn't be possible"
-                );
-            }
-            return Some(Const::from_param(tcx, qpath, expr.hir_id));
+            span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible");
         };
 
         let lit_input = match expr.kind {
@@ -396,7 +388,7 @@ impl<'tcx> Const<'tcx> {
                         Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c))
                     }
                     Ok(Err(bad_ty)) => Err(Either::Left(bad_ty)),
-                    Err(err) => Err(Either::Right(err.into())),
+                    Err(err) => Err(Either::Right(err)),
                 }
             }
             ConstKind::Value(ty, val) => Ok((ty, val)),
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 1c8916b255e..5ec7e80ee45 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2606,33 +2606,31 @@ impl<'tcx> TyCtxt<'tcx> {
     /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
     /// and print out the args if not.
     pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
-        if cfg!(debug_assertions) {
-            if !self.check_args_compatible(def_id, args) {
-                if let DefKind::AssocTy = self.def_kind(def_id)
-                    && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
-                {
-                    bug!(
-                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
-                        self.def_path_str(def_id),
-                        args,
-                        // Make `[Self, GAT_ARGS...]` (this could be simplified)
-                        self.mk_args_from_iter(
-                            [self.types.self_param.into()].into_iter().chain(
-                                self.generics_of(def_id)
-                                    .own_args(ty::GenericArgs::identity_for_item(self, def_id))
-                                    .iter()
-                                    .copied()
-                            )
+        if cfg!(debug_assertions) && !self.check_args_compatible(def_id, args) {
+            if let DefKind::AssocTy = self.def_kind(def_id)
+                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
+            {
+                bug!(
+                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                    self.def_path_str(def_id),
+                    args,
+                    // Make `[Self, GAT_ARGS...]` (this could be simplified)
+                    self.mk_args_from_iter(
+                        [self.types.self_param.into()].into_iter().chain(
+                            self.generics_of(def_id)
+                                .own_args(ty::GenericArgs::identity_for_item(self, def_id))
+                                .iter()
+                                .copied()
                         )
-                    );
-                } else {
-                    bug!(
-                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
-                        self.def_path_str(def_id),
-                        args,
-                        ty::GenericArgs::identity_for_item(self, def_id)
-                    );
-                }
+                    )
+                );
+            } else {
+                bug!(
+                    "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                    self.def_path_str(def_id),
+                    args,
+                    ty::GenericArgs::identity_for_item(self, def_id)
+                );
             }
         }
     }
@@ -3132,11 +3130,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn next_trait_solver_globally(self) -> bool {
-        self.sess.opts.unstable_opts.next_solver.globally
+        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
     }
 
     pub fn next_trait_solver_in_coherence(self) -> bool {
-        self.sess.opts.unstable_opts.next_solver.coherence
+        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
     }
 
     pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 8cec8eac189..254a0119920 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1183,10 +1183,10 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
         //
         // This is not part of `codegen_fn_attrs` as it can differ between crates
         // and therefore cannot be computed in core.
-        if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort {
-            if tcx.is_lang_item(did, LangItem::DropInPlace) {
-                return false;
-            }
+        if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort
+            && tcx.is_lang_item(did, LangItem::DropInPlace)
+        {
+            return false;
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index f1ff90831b0..988516d100f 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1526,7 +1526,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
                 let precedence = |binop: rustc_middle::mir::BinOp| {
                     use rustc_ast::util::parser::AssocOp;
-                    AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence()
+                    AssocOp::from_ast_binop(binop.to_hir_binop()).precedence()
                 };
                 let op_precedence = precedence(op);
                 let formatted_op = op.to_hir_binop().as_str();
@@ -3361,10 +3361,8 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
                     // name.
                     //
                     // Any stable ordering would be fine here though.
-                    if *v.get() != symbol {
-                        if v.get().as_str() > symbol.as_str() {
-                            v.insert(symbol);
-                        }
+                    if *v.get() != symbol && v.get().as_str() > symbol.as_str() {
+                        v.insert(symbol);
                     }
                 }
                 Vacant(v) => {
diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
index bcab54cf8ba..37dcf7c0d64 100644
--- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs
+++ b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
@@ -41,7 +41,15 @@ impl RvalueScopes {
                     debug!("temporary_scope({expr_id:?}) = {id:?} [enclosing]");
                     return Some(id);
                 }
-                _ => id = p,
+                ScopeData::IfThenRescope => {
+                    debug!("temporary_scope({expr_id:?}) = {p:?} [enclosing]");
+                    return Some(p);
+                }
+                ScopeData::Node
+                | ScopeData::CallSite
+                | ScopeData::Arguments
+                | ScopeData::IfThen
+                | ScopeData::Remainder(_) => id = p,
             }
         }
 
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
index 3aa6e708476..6019a93e787 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
@@ -268,10 +268,9 @@ impl Builder<'_, '_> {
     pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) {
         if let Some(coverage_info) = self.coverage_info.as_mut()
             && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
+            && mcdc_info.state.decision_ctx_stack.pop().is_none()
         {
-            if mcdc_info.state.decision_ctx_stack.pop().is_none() {
-                bug!("Unexpected empty decision stack");
-            }
+            bug!("Unexpected empty decision stack");
         };
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index af5940ff50e..b8b5e4634ed 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -1,7 +1,9 @@
 //! See docs in build/expr/mod.rs
 
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_hir::HirId;
 use rustc_middle::middle::region;
+use rustc_middle::middle::region::{Scope, ScopeData};
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use tracing::{debug, instrument};
@@ -73,11 +75,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 _ if let Some(tail_info) = this.block_context.currently_in_block_tail() => {
                     LocalInfo::BlockTailTemp(tail_info)
                 }
+
+                _ if let Some(Scope { data: ScopeData::IfThenRescope, id }) = temp_lifetime => {
+                    LocalInfo::IfThenRescopeTemp {
+                        if_then: HirId { owner: this.hir_id.owner, local_id: id },
+                    }
+                }
+
                 _ => LocalInfo::Boring,
             };
             **local_decl.local_info.as_mut().assert_crate_local() = local_info;
             this.local_decls.push(local_decl)
         };
+        debug!(?temp);
         if deduplicate_temps {
             this.fixed_temps.insert(expr_id, temp);
         }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 89f98a40201..aa8ccc8b7dd 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -706,7 +706,13 @@ impl<'tcx> Cx<'tcx> {
             hir::ExprKind::If(cond, then, else_opt) => ExprKind::If {
                 if_then_scope: region::Scope {
                     id: then.hir_id.local_id,
-                    data: region::ScopeData::IfThen,
+                    data: {
+                        if expr.span.at_least_rust_2024() && tcx.features().if_let_rescope {
+                            region::ScopeData::IfThenRescope
+                        } else {
+                            region::ScopeData::IfThen
+                        }
+                    },
                 },
                 cond: self.mirror_expr(cond),
                 then: self.mirror_expr(then),
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index ba4a7d76511..88a9a78f8ad 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -42,14 +42,14 @@ pub trait Direction {
     ) where
         A: GenKillAnalysis<'tcx>;
 
-    fn visit_results_in_block<'mir, 'tcx, F, R>(
-        state: &mut F,
+    fn visit_results_in_block<'mir, 'tcx, D, R>(
+        state: &mut D,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
         results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, FlowState = F>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
     ) where
-        R: ResultsVisitable<'tcx, FlowState = F>;
+        R: ResultsVisitable<'tcx, Domain = D>;
 
     fn join_state_into_successors_of<'tcx, A>(
         analysis: &mut A,
@@ -186,14 +186,14 @@ impl Direction for Backward {
         analysis.apply_statement_effect(state, statement, location);
     }
 
-    fn visit_results_in_block<'mir, 'tcx, F, R>(
-        state: &mut F,
+    fn visit_results_in_block<'mir, 'tcx, D, R>(
+        state: &mut D,
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
         results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, FlowState = F>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
     ) where
-        R: ResultsVisitable<'tcx, FlowState = F>,
+        R: ResultsVisitable<'tcx, Domain = D>,
     {
         results.reset_to_block_entry(state, block);
 
@@ -444,9 +444,9 @@ impl Direction for Forward {
         block: BasicBlock,
         block_data: &'mir mir::BasicBlockData<'tcx>,
         results: &mut R,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, FlowState = F>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = F>,
     ) where
-        R: ResultsVisitable<'tcx, FlowState = F>,
+        R: ResultsVisitable<'tcx, Domain = F>,
     {
         results.reset_to_block_entry(state, block);
 
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 0bab03b0271..54206501d9f 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -57,7 +57,7 @@ where
         &mut self,
         body: &'mir mir::Body<'tcx>,
         blocks: impl IntoIterator<Item = BasicBlock>,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, FlowState = A::Domain>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, Domain = A::Domain>,
     ) {
         visit_results(body, blocks, self, vis)
     }
@@ -65,7 +65,7 @@ where
     pub fn visit_reachable_with<'mir>(
         &mut self,
         body: &'mir mir::Body<'tcx>,
-        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, FlowState = A::Domain>,
+        vis: &mut impl ResultsVisitor<'mir, 'tcx, Self, Domain = A::Domain>,
     ) {
         let blocks = mir::traversal::reachable(body);
         visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 2e860e2d841..e72dca2c834 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -544,15 +544,15 @@ where
     A: Analysis<'tcx>,
     A::Domain: DebugWithContext<A>,
 {
-    type FlowState = A::Domain;
+    type Domain = A::Domain;
 
-    fn visit_block_start(&mut self, state: &Self::FlowState) {
+    fn visit_block_start(&mut self, state: &Self::Domain) {
         if A::Direction::IS_FORWARD {
             self.prev_state.clone_from(state);
         }
     }
 
-    fn visit_block_end(&mut self, state: &Self::FlowState) {
+    fn visit_block_end(&mut self, state: &Self::Domain) {
         if A::Direction::IS_BACKWARD {
             self.prev_state.clone_from(state);
         }
@@ -561,7 +561,7 @@ where
     fn visit_statement_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -574,7 +574,7 @@ where
     fn visit_statement_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _statement: &mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -585,7 +585,7 @@ where
     fn visit_terminator_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
@@ -598,7 +598,7 @@ where
     fn visit_terminator_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, A>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _terminator: &mir::Terminator<'tcx>,
         _location: Location,
     ) {
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index 8b8a16bda99..3d6b008a684 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -4,15 +4,15 @@ use super::{Analysis, Direction, Results};
 
 /// Calls the corresponding method in `ResultsVisitor` for every location in a `mir::Body` with the
 /// dataflow state at that location.
-pub fn visit_results<'mir, 'tcx, F, R>(
+pub fn visit_results<'mir, 'tcx, D, R>(
     body: &'mir mir::Body<'tcx>,
     blocks: impl IntoIterator<Item = BasicBlock>,
     results: &mut R,
-    vis: &mut impl ResultsVisitor<'mir, 'tcx, R, FlowState = F>,
+    vis: &mut impl ResultsVisitor<'mir, 'tcx, R, Domain = D>,
 ) where
-    R: ResultsVisitable<'tcx, FlowState = F>,
+    R: ResultsVisitable<'tcx, Domain = D>,
 {
-    let mut state = results.new_flow_state(body);
+    let mut state = results.bottom_value(body);
 
     #[cfg(debug_assertions)]
     let reachable_blocks = mir::traversal::reachable_as_bitset(body);
@@ -29,16 +29,16 @@ pub fn visit_results<'mir, 'tcx, F, R>(
 /// A visitor over the results of an `Analysis`. The type parameter `R` is the results type being
 /// visited.
 pub trait ResultsVisitor<'mir, 'tcx, R> {
-    type FlowState;
+    type Domain;
 
-    fn visit_block_start(&mut self, _state: &Self::FlowState) {}
+    fn visit_block_start(&mut self, _state: &Self::Domain) {}
 
     /// Called with the `before_statement_effect` of the given statement applied to `state` but not
     /// its `statement_effect`.
     fn visit_statement_before_primary_effect(
         &mut self,
         _results: &mut R,
-        _state: &Self::FlowState,
+        _state: &Self::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -49,7 +49,7 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
     fn visit_statement_after_primary_effect(
         &mut self,
         _results: &mut R,
-        _state: &Self::FlowState,
+        _state: &Self::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         _location: Location,
     ) {
@@ -60,7 +60,7 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
     fn visit_terminator_before_primary_effect(
         &mut self,
         _results: &mut R,
-        _state: &Self::FlowState,
+        _state: &Self::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         _location: Location,
     ) {
@@ -73,13 +73,13 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
     fn visit_terminator_after_primary_effect(
         &mut self,
         _results: &mut R,
-        _state: &Self::FlowState,
+        _state: &Self::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         _location: Location,
     ) {
     }
 
-    fn visit_block_end(&mut self, _state: &Self::FlowState) {}
+    fn visit_block_end(&mut self, _state: &Self::Domain) {}
 }
 
 /// Things that can be visited by a `ResultsVisitor`.
@@ -88,40 +88,40 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
 /// simultaneously.
 pub trait ResultsVisitable<'tcx> {
     type Direction: Direction;
-    type FlowState;
+    type Domain;
 
-    /// Creates an empty `FlowState` to hold the transient state for these dataflow results.
+    /// Creates an empty `Domain` to hold the transient state for these dataflow results.
     ///
-    /// The value of the newly created `FlowState` will be overwritten by `reset_to_block_entry`
+    /// The value of the newly created `Domain` will be overwritten by `reset_to_block_entry`
     /// before it can be observed by a `ResultsVisitor`.
-    fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState;
+    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain;
 
-    fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock);
+    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock);
 
     fn reconstruct_before_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
         location: Location,
     );
 
     fn reconstruct_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         statement: &mir::Statement<'tcx>,
         location: Location,
     );
 
     fn reconstruct_before_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         terminator: &mir::Terminator<'tcx>,
         location: Location,
     );
 
     fn reconstruct_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         terminator: &mir::Terminator<'tcx>,
         location: Location,
     );
@@ -131,21 +131,20 @@ impl<'tcx, A> ResultsVisitable<'tcx> for Results<'tcx, A>
 where
     A: Analysis<'tcx>,
 {
-    type FlowState = A::Domain;
-
+    type Domain = A::Domain;
     type Direction = A::Direction;
 
-    fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
+    fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
         self.analysis.bottom_value(body)
     }
 
-    fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
+    fn reset_to_block_entry(&self, state: &mut Self::Domain, block: BasicBlock) {
         state.clone_from(self.entry_set_for_block(block));
     }
 
     fn reconstruct_before_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
@@ -154,7 +153,7 @@ where
 
     fn reconstruct_statement_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         stmt: &mir::Statement<'tcx>,
         loc: Location,
     ) {
@@ -163,7 +162,7 @@ where
 
     fn reconstruct_before_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
@@ -172,7 +171,7 @@ where
 
     fn reconstruct_terminator_effect(
         &mut self,
-        state: &mut Self::FlowState,
+        state: &mut Self::Domain,
         term: &mir::Terminator<'tcx>,
         loc: Location,
     ) {
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index e8e78fb8a89..8b082ef2667 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -11,7 +11,7 @@ use crate::{AnalysisDomain, GenKill, GenKillAnalysis};
 /// At present, this is used as a very limited form of alias analysis. For example,
 /// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
 /// immovable coroutines.
-#[derive(Clone, Copy)]
+#[derive(Clone)]
 pub struct MaybeBorrowedLocals;
 
 impl MaybeBorrowedLocals {
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index 24a4b32ceb7..1559c131a37 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -217,7 +217,6 @@ impl DefUse {
 /// This is basically written for dead store elimination and nothing else.
 ///
 /// All of the caveats of `MaybeLiveLocals` apply.
-#[derive(Clone, Copy)]
 pub struct MaybeTransitiveLiveLocals<'a> {
     always_live: &'a BitSet<Local>,
 }
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 9f2f0187698..6bf54c8db41 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -7,7 +7,6 @@ use rustc_middle::mir::*;
 use super::MaybeBorrowedLocals;
 use crate::{GenKill, ResultsCursor};
 
-#[derive(Clone)]
 pub struct MaybeStorageLive<'a> {
     always_live_locals: Cow<'a, BitSet<Local>>,
 }
@@ -80,7 +79,6 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> {
     }
 }
 
-#[derive(Clone)]
 pub struct MaybeStorageDead<'a> {
     always_live_locals: Cow<'a, BitSet<Local>>,
 }
diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs
index 4be7492366a..adfa94464a0 100644
--- a/compiler/rustc_mir_dataflow/src/points.rs
+++ b/compiler/rustc_mir_dataflow/src/points.rs
@@ -102,7 +102,7 @@ pub fn save_as_intervals<'tcx, N, R>(
 ) -> SparseIntervalMatrix<N, PointIndex>
 where
     N: Idx,
-    R: ResultsVisitable<'tcx, FlowState = BitSet<N>>,
+    R: ResultsVisitable<'tcx, Domain = BitSet<N>>,
 {
     let values = SparseIntervalMatrix::new(elements.num_points());
     let mut visitor = Visitor { elements, values };
@@ -124,12 +124,12 @@ impl<'mir, 'tcx, R, N> ResultsVisitor<'mir, 'tcx, R> for Visitor<'_, N>
 where
     N: Idx,
 {
-    type FlowState = BitSet<N>;
+    type Domain = BitSet<N>;
 
     fn visit_statement_after_primary_effect(
         &mut self,
         _results: &mut R,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _statement: &'mir mir::Statement<'tcx>,
         location: Location,
     ) {
@@ -143,7 +143,7 @@ where
     fn visit_terminator_after_primary_effect(
         &mut self,
         _results: &mut R,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _terminator: &'mir mir::Terminator<'tcx>,
         location: Location,
     ) {
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 8c3e6f49b16..ac9b853f21b 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -229,7 +229,7 @@ trait RustcPeekAt<'tcx>: Analysis<'tcx> {
         &self,
         tcx: TyCtxt<'tcx>,
         place: mir::Place<'tcx>,
-        flow_state: &Self::Domain,
+        state: &Self::Domain,
         call: PeekCall,
     );
 }
@@ -243,12 +243,12 @@ where
         &self,
         tcx: TyCtxt<'tcx>,
         place: mir::Place<'tcx>,
-        flow_state: &Self::Domain,
+        state: &Self::Domain,
         call: PeekCall,
     ) {
         match self.move_data().rev_lookup.find(place.as_ref()) {
             LookupResult::Exact(peek_mpi) => {
-                let bit_state = flow_state.contains(peek_mpi);
+                let bit_state = state.contains(peek_mpi);
                 debug!("rustc_peek({:?} = &{:?}) bit_state: {}", call.arg, place, bit_state);
                 if !bit_state {
                     tcx.dcx().emit_err(PeekBitNotSet { span: call.span });
@@ -267,7 +267,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
         &self,
         tcx: TyCtxt<'tcx>,
         place: mir::Place<'tcx>,
-        flow_state: &BitSet<Local>,
+        state: &BitSet<Local>,
         call: PeekCall,
     ) {
         info!(?place, "peek_at");
@@ -276,7 +276,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
             return;
         };
 
-        if !flow_state.contains(local) {
+        if !state.contains(local) {
             tcx.dcx().emit_err(PeekBitNotSet { span: call.span });
         }
     }
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 048dd9ccb8f..9c3cbbe1fc9 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -95,19 +95,19 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
             // Check for assignment to fields of a constant
             // Assigning directly to a constant (e.g. `FOO = true;`) is a hard error,
             // so emitting a lint would be redundant.
-            if !lhs.projection.is_empty() {
-                if let Some(def_id) = self.is_const_item_without_destructor(lhs.local)
-                    && let Some((lint_root, span, item)) =
-                        self.should_lint_const_item_usage(lhs, def_id, loc)
-                {
-                    self.tcx.emit_node_span_lint(
-                        CONST_ITEM_MUTATION,
-                        lint_root,
-                        span,
-                        errors::ConstMutate::Modify { konst: item },
-                    );
-                }
+            if !lhs.projection.is_empty()
+                && let Some(def_id) = self.is_const_item_without_destructor(lhs.local)
+                && let Some((lint_root, span, item)) =
+                    self.should_lint_const_item_usage(lhs, def_id, loc)
+            {
+                self.tcx.emit_node_span_lint(
+                    CONST_ITEM_MUTATION,
+                    lint_root,
+                    span,
+                    errors::ConstMutate::Modify { konst: item },
+                );
             }
+
             // We are looking for MIR of the form:
             //
             // ```
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 90243cd2910..1fb74f5d82c 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -885,12 +885,12 @@ struct StorageConflictVisitor<'a, 'tcx> {
 impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
     for StorageConflictVisitor<'a, 'tcx>
 {
-    type FlowState = BitSet<Local>;
+    type Domain = BitSet<Local>;
 
     fn visit_statement_before_primary_effect(
         &mut self,
         _results: &mut R,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _statement: &'a Statement<'tcx>,
         loc: Location,
     ) {
@@ -900,7 +900,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
     fn visit_terminator_before_primary_effect(
         &mut self,
         _results: &mut R,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         _terminator: &'a Terminator<'tcx>,
         loc: Location,
     ) {
@@ -909,13 +909,13 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
 }
 
 impl StorageConflictVisitor<'_, '_> {
-    fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
+    fn apply_state(&mut self, state: &BitSet<Local>, loc: Location) {
         // Ignore unreachable blocks.
         if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind {
             return;
         }
 
-        self.eligible_storage_live.clone_from(flow_state);
+        self.eligible_storage_live.clone_from(state);
         self.eligible_storage_live.intersect(&**self.saved_locals);
 
         for local in self.eligible_storage_live.iter() {
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 1c240366afa..7e3ecad1bce 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -155,12 +155,14 @@ impl CoverageCounters {
         BcbCounter::Expression { id }
     }
 
-    /// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`].
+    /// Creates a counter that is the sum of the given counters.
     ///
-    /// This is useful when using [`Iterator::fold`] to build an arbitrary-length sum.
-    fn make_sum_expression(&mut self, lhs: Option<BcbCounter>, rhs: BcbCounter) -> BcbCounter {
-        let Some(lhs) = lhs else { return rhs };
-        self.make_expression(lhs, Op::Add, rhs)
+    /// Returns `None` if the given list of counters was empty.
+    fn make_sum(&mut self, counters: &[BcbCounter]) -> Option<BcbCounter> {
+        counters
+            .iter()
+            .copied()
+            .reduce(|accum, counter| self.make_expression(accum, Op::Add, counter))
     }
 
     pub(super) fn num_counters(&self) -> usize {
@@ -315,20 +317,17 @@ impl<'a> MakeBcbCounters<'a> {
         // For each out-edge other than the one that was chosen to get an expression,
         // ensure that it has a counter (existing counter/expression or a new counter),
         // and accumulate the corresponding counters into a single sum expression.
-        let sum_of_all_other_out_edges: BcbCounter = {
-            let _span = debug_span!("sum_of_all_other_out_edges", ?expression_to_bcb).entered();
-            successors
-                .iter()
-                .copied()
-                // Skip the chosen edge, since we'll calculate its count from this sum.
-                .filter(|&to_bcb| to_bcb != expression_to_bcb)
-                .fold(None, |accum, to_bcb| {
-                    let _span = debug_span!("to_bcb", ?accum, ?to_bcb).entered();
-                    let edge_counter = self.get_or_make_edge_counter(from_bcb, to_bcb);
-                    Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
-                })
-                .expect("there must be at least one other out-edge")
-        };
+        let other_out_edge_counters = successors
+            .iter()
+            .copied()
+            // Skip the chosen edge, since we'll calculate its count from this sum.
+            .filter(|&to_bcb| to_bcb != expression_to_bcb)
+            .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb))
+            .collect::<Vec<_>>();
+        let sum_of_all_other_out_edges: BcbCounter = self
+            .coverage_counters
+            .make_sum(&other_out_edge_counters)
+            .expect("there must be at least one other out-edge");
 
         // Now create an expression for the chosen edge, by taking the counter
         // for its source node and subtracting the sum of its sibling out-edges.
@@ -375,20 +374,15 @@ impl<'a> MakeBcbCounters<'a> {
 
         // A BCB with multiple incoming edges can compute its count by ensuring that counters
         // exist for each of those edges, and then adding them up to get a total count.
-        let sum_of_in_edges: BcbCounter = {
-            let _span = debug_span!("sum_of_in_edges", ?bcb).entered();
-            // We avoid calling `self.bcb_predecessors` here so that we can
-            // call methods on `&mut self` inside the fold.
-            self.basic_coverage_blocks.predecessors[bcb]
-                .iter()
-                .copied()
-                .fold(None, |accum, from_bcb| {
-                    let _span = debug_span!("from_bcb", ?accum, ?from_bcb).entered();
-                    let edge_counter = self.get_or_make_edge_counter(from_bcb, bcb);
-                    Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
-                })
-                .expect("there must be at least one in-edge")
-        };
+        let in_edge_counters = self.basic_coverage_blocks.predecessors[bcb]
+            .iter()
+            .copied()
+            .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb))
+            .collect::<Vec<_>>();
+        let sum_of_in_edges: BcbCounter = self
+            .coverage_counters
+            .make_sum(&in_edge_counters)
+            .expect("there must be at least one in-edge");
 
         debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
         self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges)
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 7ac019ce812..ad9f9162606 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -724,13 +724,13 @@ impl<'mir, 'tcx>
     ResultsVisitor<'mir, 'tcx, Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>>
     for Collector<'tcx, '_>
 {
-    type FlowState = State<FlatSet<Scalar>>;
+    type Domain = State<FlatSet<Scalar>>;
 
     #[instrument(level = "trace", skip(self, results, statement))]
     fn visit_statement_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         statement: &'mir Statement<'tcx>,
         location: Location,
     ) {
@@ -752,7 +752,7 @@ impl<'mir, 'tcx>
     fn visit_statement_after_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         statement: &'mir Statement<'tcx>,
         location: Location,
     ) {
@@ -777,7 +777,7 @@ impl<'mir, 'tcx>
     fn visit_terminator_before_primary_effect(
         &mut self,
         results: &mut Results<'tcx, ValueAnalysisWrapper<ConstAnalysis<'_, 'tcx>>>,
-        state: &Self::FlowState,
+        state: &Self::Domain,
         terminator: &'mir Terminator<'tcx>,
         location: Location,
     ) {
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index c645bbee08a..c0cb0e641ac 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -168,17 +168,16 @@ pub(super) fn deduced_param_attrs<'tcx>(
     // Codegen won't use this information for anything if all the function parameters are passed
     // directly. Detect that and bail, for compilation speed.
     let fn_ty = tcx.type_of(def_id).instantiate_identity();
-    if matches!(fn_ty.kind(), ty::FnDef(..)) {
-        if fn_ty
+    if matches!(fn_ty.kind(), ty::FnDef(..))
+        && fn_ty
             .fn_sig(tcx)
             .inputs()
             .skip_binder()
             .iter()
             .cloned()
             .all(type_will_always_be_passed_directly)
-        {
-            return &[];
-        }
+    {
+        return &[];
     }
 
     // Don't deduce any attributes for functions that have no MIR.
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 46b17c3c7e0..f123f39bf42 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -378,19 +378,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         if let (Some(l), Some(r)) = (l, r)
             && l.layout.ty.is_integral()
             && op.is_overflowing()
-        {
-            if self.use_ecx(|this| {
+            && self.use_ecx(|this| {
                 let (_res, overflow) = this.ecx.binary_op(op, &l, &r)?.to_scalar_pair();
                 overflow.to_bool()
-            })? {
-                self.report_assert_as_lint(
-                    location,
-                    AssertLintKind::ArithmeticOverflow,
-                    AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
-                );
-                return None;
-            }
+            })?
+        {
+            self.report_assert_as_lint(
+                location,
+                AssertLintKind::ArithmeticOverflow,
+                AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
+            );
+            return None;
         }
+
         Some(())
     }
 
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 60ece5e7db9..29f8b4f6e4d 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -42,7 +42,7 @@ fn to_profiler_name(type_name: &'static str) -> &'static str {
 
 // const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
 const fn c_name(name: &'static str) -> &'static str {
-    // FIXME Simplify the implementation once more `str` methods get const-stable.
+    // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
     // and inline into call site
     let bytes = name.as_bytes();
     let mut i = bytes.len();
@@ -61,7 +61,7 @@ const fn c_name(name: &'static str) -> &'static str {
 /// loop that goes over each available MIR and applies `run_pass`.
 pub(super) trait MirPass<'tcx> {
     fn name(&self) -> &'static str {
-        // FIXME Simplify the implementation once more `str` methods get const-stable.
+        // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
         // See copypaste in `MirLint`
         const {
             let name = std::any::type_name::<Self>();
@@ -89,7 +89,7 @@ pub(super) trait MirPass<'tcx> {
 /// disabled (via the `Lint` adapter).
 pub(super) trait MirLint<'tcx> {
     fn name(&self) -> &'static str {
-        // FIXME Simplify the implementation once more `str` methods get const-stable.
+        // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
         // See copypaste in `MirPass`
         const {
             let name = std::any::type_name::<Self>();
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 0d295b8f280..2d9dbdbaec2 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -504,10 +504,8 @@ fn compute_inlined_overlap<'tcx>(cgu1: &CodegenUnit<'tcx>, cgu2: &CodegenUnit<'t
 
     let mut overlap = 0;
     for (item, data) in src_cgu.items().iter() {
-        if data.inlined {
-            if dst_cgu.items().contains_key(item) {
-                overlap += data.size_estimate;
-            }
+        if data.inlined && dst_cgu.items().contains_key(item) {
+            overlap += data.size_estimate;
         }
     }
     overlap
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 394518daa42..196ddeb2443 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -185,10 +185,8 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
                 for var in var_infos.iter_mut() {
                     // We simply put all regions from the input into the highest
                     // compressed universe, so we only deal with them at the end.
-                    if !var.is_region() {
-                        if is_existential == var.is_existential() {
-                            update_uv(var, orig_uv, is_existential)
-                        }
+                    if !var.is_region() && is_existential == var.is_existential() {
+                        update_uv(var, orig_uv, is_existential)
                     }
                 }
             }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 1c00f5f8b41..5acfec3dee3 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -122,6 +122,21 @@ where
             (certainty, NestedNormalizationGoals::empty())
         };
 
+        if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty {
+            // If we have overflow, it's probable that we're substituting a type
+            // into itself infinitely and any partial substitutions in the query
+            // response are probably not useful anyways, so just return an empty
+            // query response.
+            //
+            // This may prevent us from potentially useful inference, e.g.
+            // 2 candidates, one ambiguous and one overflow, which both
+            // have the same inference constraints.
+            //
+            // Changing this to retain some constraints in the future
+            // won't be a breaking change, so this is good enough for now.
+            return Ok(self.make_ambiguous_response_no_constraints(cause));
+        }
+
         let external_constraints =
             self.compute_external_query_constraints(certainty, normalization_nested_goals);
         let (var_values, mut external_constraints) = (self.var_values, external_constraints)
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 3f2f34d3255..15b123ebdf9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -17,7 +17,7 @@ use crate::delegate::SolverDelegate;
 use crate::solve::inspect::{self, ProofTreeBuilder};
 use crate::solve::search_graph::SearchGraph;
 use crate::solve::{
-    CanonicalInput, CanonicalResponse, Certainty, Goal, GoalEvaluationKind, GoalSource, MaybeCause,
+    CanonicalInput, CanonicalResponse, Certainty, Goal, GoalEvaluationKind, GoalSource,
     NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult, SolverMode,
     FIXPOINT_STEP_LIMIT,
 };
@@ -370,7 +370,7 @@ where
             canonical_goal,
             &mut goal_evaluation,
         );
-        let canonical_response = match canonical_response {
+        let response = match canonical_response {
             Err(e) => {
                 self.inspect.goal_evaluation(goal_evaluation);
                 return Err(e);
@@ -378,12 +378,11 @@ where
             Ok(response) => response,
         };
 
-        let (normalization_nested_goals, certainty, has_changed) = self
-            .instantiate_response_discarding_overflow(
-                goal.param_env,
-                orig_values,
-                canonical_response,
-            );
+        let has_changed = !response.value.var_values.is_identity_modulo_regions()
+            || !response.value.external_constraints.opaque_types.is_empty();
+
+        let (normalization_nested_goals, certainty) =
+            self.instantiate_and_apply_query_response(goal.param_env, orig_values, response);
         self.inspect.goal_evaluation(goal_evaluation);
         // FIXME: We previously had an assert here that checked that recomputing
         // a goal after applying its constraints did not change its response.
@@ -398,24 +397,6 @@ where
         Ok((normalization_nested_goals, has_changed, certainty))
     }
 
-    fn instantiate_response_discarding_overflow(
-        &mut self,
-        param_env: I::ParamEnv,
-        original_values: Vec<I::GenericArg>,
-        response: CanonicalResponse<I>,
-    ) -> (NestedNormalizationGoals<I>, Certainty, bool) {
-        if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty {
-            return (NestedNormalizationGoals::empty(), response.value.certainty, false);
-        }
-
-        let has_changed = !response.value.var_values.is_identity_modulo_regions()
-            || !response.value.external_constraints.opaque_types.is_empty();
-
-        let (normalization_nested_goals, certainty) =
-            self.instantiate_and_apply_query_response(param_env, original_values, response);
-        (normalization_nested_goals, certainty, has_changed)
-    }
-
     fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
         let Goal { param_env, predicate } = goal;
         let kind = predicate.kind();
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 683d8dab3b2..73d9b5e8a4e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -883,7 +883,6 @@ where
             .into_iter()
             .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
                 elaborate::supertrait_def_ids(self.cx(), principal_def_id)
-                    .into_iter()
                     .filter(|def_id| self.cx().trait_is_auto(*def_id))
             }))
             .collect();
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 205cca830b2..6a241be0a15 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -383,7 +383,7 @@ impl<'a> Parser<'a> {
             self.capture_state
                 .parser_replacements
                 .drain(parser_replacements_start..parser_replacements_end)
-                .chain(inner_attr_parser_replacements.into_iter())
+                .chain(inner_attr_parser_replacements)
                 .map(|(parser_range, data)| {
                     (NodeRange::new(parser_range, collect_pos.start_pos), data)
                 })
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ecc4cd96faf..2d6edad2977 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2554,13 +2554,12 @@ impl<'a> Parser<'a> {
             let maybe_fatarrow = self.token.clone();
             let block = if self.check(&token::OpenDelim(Delimiter::Brace)) {
                 self.parse_block()?
+            } else if let Some(block) = recover_block_from_condition(self) {
+                block
             } else {
-                if let Some(block) = recover_block_from_condition(self) {
-                    block
-                } else {
-                    self.error_on_extra_if(&cond)?;
-                    // Parse block, which will always fail, but we can add a nice note to the error
-                    self.parse_block().map_err(|mut err| {
+                self.error_on_extra_if(&cond)?;
+                // Parse block, which will always fail, but we can add a nice note to the error
+                self.parse_block().map_err(|mut err| {
                         if self.prev_token == token::Semi
                             && self.token == token::AndAnd
                             && let maybe_let = self.look_ahead(1, |t| t.clone())
@@ -2592,7 +2591,6 @@ impl<'a> Parser<'a> {
                         }
                         err
                     })?
-                }
             };
             self.error_on_if_block_attrs(lo, false, block.span, attrs);
             block
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 83d10dea6a8..104678e081c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1588,7 +1588,7 @@ impl<'a> Parser<'a> {
                             (thin_vec![], Recovered::Yes(guar))
                         }
                     };
-                VariantData::Struct { fields, recovered: recovered.into() }
+                VariantData::Struct { fields, recovered }
             } else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) {
                 let body = match this.parse_tuple_struct_body() {
                     Ok(body) => body,
@@ -1672,7 +1672,7 @@ impl<'a> Parser<'a> {
                     class_name.span,
                     generics.where_clause.has_where_token,
                 )?;
-                VariantData::Struct { fields, recovered: recovered.into() }
+                VariantData::Struct { fields, recovered }
             }
         // No `where` so: `struct Foo<T>;`
         } else if self.eat(&token::Semi) {
@@ -1684,7 +1684,7 @@ impl<'a> Parser<'a> {
                 class_name.span,
                 generics.where_clause.has_where_token,
             )?;
-            VariantData::Struct { fields, recovered: recovered.into() }
+            VariantData::Struct { fields, recovered }
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(Delimiter::Parenthesis) {
             let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
@@ -1713,14 +1713,14 @@ impl<'a> Parser<'a> {
                 class_name.span,
                 generics.where_clause.has_where_token,
             )?;
-            VariantData::Struct { fields, recovered: recovered.into() }
+            VariantData::Struct { fields, recovered }
         } else if self.token == token::OpenDelim(Delimiter::Brace) {
             let (fields, recovered) = self.parse_record_struct_body(
                 "union",
                 class_name.span,
                 generics.where_clause.has_where_token,
             )?;
-            VariantData::Struct { fields, recovered: recovered.into() }
+            VariantData::Struct { fields, recovered }
         } else {
             let token_str = super::token_descr(&self.token);
             let msg = format!("expected `where` or `{{` after union name, found {token_str}");
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 3ee6e742d1b..9d9265d5318 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1359,13 +1359,11 @@ impl<'a> Parser<'a> {
     fn parse_attr_args(&mut self) -> PResult<'a, AttrArgs> {
         Ok(if let Some(args) = self.parse_delim_args_inner() {
             AttrArgs::Delimited(args)
+        } else if self.eat(&token::Eq) {
+            let eq_span = self.prev_token.span;
+            AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?))
         } else {
-            if self.eat(&token::Eq) {
-                let eq_span = self.prev_token.span;
-                AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?))
-            } else {
-                AttrArgs::Empty
-            }
+            AttrArgs::Empty
         })
     }
 
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index cbd35ffdfa9..daced411b8f 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1336,21 +1336,19 @@ impl<'a> Parser<'a> {
                         vec![(first_etc_span, String::new())],
                         Applicability::MachineApplicable,
                     );
-                } else {
-                    if let Some(last_non_comma_dotdot_span) = last_non_comma_dotdot_span {
-                        // We have `.., x`.
-                        err.multipart_suggestion(
-                            "move the `..` to the end of the field list",
-                            vec![
-                                (first_etc_span, String::new()),
-                                (
-                                    self.token.span.to(last_non_comma_dotdot_span.shrink_to_hi()),
-                                    format!("{} .. }}", if ate_comma { "" } else { "," }),
-                                ),
-                            ],
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                } else if let Some(last_non_comma_dotdot_span) = last_non_comma_dotdot_span {
+                    // We have `.., x`.
+                    err.multipart_suggestion(
+                        "move the `..` to the end of the field list",
+                        vec![
+                            (first_etc_span, String::new()),
+                            (
+                                self.token.span.to(last_non_comma_dotdot_span.shrink_to_hi()),
+                                format!("{} .. }}", if ate_comma { "" } else { "," }),
+                            ),
+                        ],
+                        Applicability::MachineApplicable,
+                    );
                 }
             }
             err.emit();
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 8ee40ecd77e..42039c621d6 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -671,12 +671,12 @@ impl<'a> Parser<'a> {
                     err.emit();
                     continue;
                 }
-                if !self.token.kind.should_end_const_arg() {
-                    if self.handle_ambiguous_unbraced_const_arg(&mut args)? {
-                        // We've managed to (partially) recover, so continue trying to parse
-                        // arguments.
-                        continue;
-                    }
+                if !self.token.kind.should_end_const_arg()
+                    && self.handle_ambiguous_unbraced_const_arg(&mut args)?
+                {
+                    // We've managed to (partially) recover, so continue trying to parse
+                    // arguments.
+                    continue;
                 }
                 break;
             }
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index fce41bd90be..f2121c3243a 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -192,13 +192,11 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
                 );
             }
         }
-    } else {
-        if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
-            psess.dcx().emit_err(errors::InvalidAttrUnsafe {
-                span: unsafe_span,
-                name: attr_item.path.clone(),
-            });
-        }
+    } else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
+        psess.dcx().emit_err(errors::InvalidAttrUnsafe {
+            span: unsafe_span,
+            name: attr_item.path.clone(),
+        });
     }
 }
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4fb9b93b80c..ee892c17376 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2169,17 +2169,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     attr.span,
                     errors::MacroExport::TooManyItems,
                 );
-            } else {
-                if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
-                    self.tcx.emit_node_span_lint(
-                        INVALID_MACRO_EXPORT_ARGUMENTS,
-                        hir_id,
-                        meta_item_list[0].span(),
-                        errors::MacroExport::UnknownItem {
-                            name: meta_item_list[0].name_or_empty(),
-                        },
-                    );
-                }
+            } else if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
+                self.tcx.emit_node_span_lint(
+                    INVALID_MACRO_EXPORT_ARGUMENTS,
+                    hir_id,
+                    meta_item_list[0].span(),
+                    errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() },
+                );
             }
         } else {
             // special case when `#[macro_export]` is applied to a macro 2.0
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index db3eaea68b5..959b7ad147b 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1500,15 +1500,13 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             );
                         }
                     }
-                } else {
-                    if let Some(name) = self.should_warn(var) {
-                        self.ir.tcx.emit_node_span_lint(
-                            lint::builtin::UNUSED_VARIABLES,
-                            var_hir_id,
-                            vec![span],
-                            errors::UnusedVarMaybeCaptureRef { name },
-                        );
-                    }
+                } else if let Some(name) = self.should_warn(var) {
+                    self.ir.tcx.emit_node_span_lint(
+                        lint::builtin::UNUSED_VARIABLES,
+                        var_hir_id,
+                        vec![span],
+                        errors::UnusedVarMaybeCaptureRef { name },
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index ba4c300ea61..e2c9067c0b9 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -174,16 +174,14 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
 
         // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI,
         // check if the function/method is const or the parent impl block is const
-        if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) {
-            if fn_sig.header.abi != Abi::RustIntrinsic && !fn_sig.header.is_const() {
-                if !self.in_trait_impl
-                    || (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id()))
-                {
-                    self.tcx
-                        .dcx()
-                        .emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span, const_span });
-                }
-            }
+        if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig)
+            && fn_sig.header.abi != Abi::RustIntrinsic
+            && !fn_sig.header.is_const()
+            && (!self.in_trait_impl || !self.tcx.is_const_fn_raw(def_id.to_def_id()))
+        {
+            self.tcx
+                .dcx()
+                .emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span, const_span });
         }
 
         // `impl const Trait for Type` items forward their const stability to their
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 3ea782b62f1..f87f3cdde4c 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -39,10 +39,10 @@ use crate::{
 
 type Res = def::Res<NodeId>;
 
-impl<'a, Id: Into<DefId>> ToNameBinding<'a>
-    for (Module<'a>, ty::Visibility<Id>, Span, LocalExpnId)
+impl<'ra, Id: Into<DefId>> ToNameBinding<'ra>
+    for (Module<'ra>, ty::Visibility<Id>, Span, LocalExpnId)
 {
-    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> {
+    fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
         arenas.alloc_name_binding(NameBindingData {
             kind: NameBindingKind::Module(self.0),
             ambiguity: None,
@@ -54,8 +54,8 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a>
     }
 }
 
-impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
-    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> {
+impl<'ra, Id: Into<DefId>> ToNameBinding<'ra> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
+    fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
         arenas.alloc_name_binding(NameBindingData {
             kind: NameBindingKind::Res(self.0),
             ambiguity: None,
@@ -67,12 +67,12 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span,
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    pub(crate) fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+    pub(crate) fn define<T>(&mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, def: T)
     where
-        T: ToNameBinding<'a>,
+        T: ToNameBinding<'ra>,
     {
         let binding = def.to_name_binding(self.arenas);
         let key = self.new_disambiguated_key(ident, ns);
@@ -97,7 +97,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
     /// but they cannot use def-site hygiene, so the assumption holds
     /// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
-    pub(crate) fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'a> {
+    pub(crate) fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'ra> {
         loop {
             match self.get_module(def_id) {
                 Some(module) => return module,
@@ -106,14 +106,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    pub(crate) fn expect_module(&mut self, def_id: DefId) -> Module<'a> {
+    pub(crate) fn expect_module(&mut self, def_id: DefId) -> Module<'ra> {
         self.get_module(def_id).expect("argument `DefId` is not a module")
     }
 
     /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
     /// or trait), then this function returns that module's resolver representation, otherwise it
     /// returns `None`.
-    pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> {
+    pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'ra>> {
         if let module @ Some(..) = self.module_map.get(&def_id) {
             return module.copied();
         }
@@ -143,7 +143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         None
     }
 
-    pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
+    pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'ra> {
         match expn_id.expn_data().macro_def_id {
             Some(def_id) => self.macro_def_scope(def_id),
             None => expn_id
@@ -153,7 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> {
+    pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'ra> {
         if let Some(id) = def_id.as_local() {
             self.local_macro_def_scopes[&id]
         } else {
@@ -186,15 +186,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn build_reduced_graph(
         &mut self,
         fragment: &AstFragment,
-        parent_scope: ParentScope<'a>,
-    ) -> MacroRulesScopeRef<'a> {
+        parent_scope: ParentScope<'ra>,
+    ) -> MacroRulesScopeRef<'ra> {
         collect_definitions(self, fragment, parent_scope.expansion);
         let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
         fragment.visit_with(&mut visitor);
         visitor.parent_scope.macro_rules
     }
 
-    pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
+    pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'ra>) {
         for child in self.tcx.module_children(module.def_id()) {
             let parent_scope = ParentScope::module(module, self);
             self.build_reduced_graph_for_external_crate_res(child, parent_scope)
@@ -205,7 +205,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn build_reduced_graph_for_external_crate_res(
         &mut self,
         child: &ModChild,
-        parent_scope: ParentScope<'a>,
+        parent_scope: ParentScope<'ra>,
     ) {
         let parent = parent_scope.module;
         let ModChild { ident, res, vis, ref reexport_chain } = *child;
@@ -273,18 +273,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 }
 
-struct BuildReducedGraphVisitor<'a, 'b, 'tcx> {
-    r: &'b mut Resolver<'a, 'tcx>,
-    parent_scope: ParentScope<'a>,
+struct BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
+    r: &'a mut Resolver<'ra, 'tcx>,
+    parent_scope: ParentScope<'ra>,
 }
 
-impl<'a, 'tcx> AsMut<Resolver<'a, 'tcx>> for BuildReducedGraphVisitor<'a, '_, 'tcx> {
-    fn as_mut(&mut self) -> &mut Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for BuildReducedGraphVisitor<'_, 'ra, 'tcx> {
+    fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
         self.r
     }
 }
 
-impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     fn res(&self, def_id: impl Into<DefId>) -> Res {
         let def_id = def_id.into();
         Res::Def(self.r.tcx.def_kind(def_id), def_id)
@@ -424,7 +424,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     fn add_import(
         &mut self,
         module_path: Vec<Segment>,
-        kind: ImportKind<'a>,
+        kind: ImportKind<'ra>,
         span: Span,
         item: &ast::Item,
         root_span: Span,
@@ -752,7 +752,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     }
 
     /// Constructs the reduced graph for one item.
-    fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
+    fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
         let parent_scope = &self.parent_scope;
         let parent = parent_scope.module;
         let expansion = parent_scope.expansion;
@@ -918,7 +918,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         item: &Item,
         local_def_id: LocalDefId,
         vis: ty::Visibility,
-        parent: Module<'a>,
+        parent: Module<'ra>,
     ) {
         let ident = item.ident;
         let sp = item.span;
@@ -1040,7 +1040,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     fn add_macro_use_binding(
         &mut self,
         name: Symbol,
-        binding: NameBinding<'a>,
+        binding: NameBinding<'ra>,
         span: Span,
         allow_shadowing: bool,
     ) {
@@ -1050,7 +1050,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     }
 
     /// Returns `true` if we should consider the underlying `extern crate` to be used.
-    fn process_macro_use_imports(&mut self, item: &Item, module: Module<'a>) -> bool {
+    fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
         let mut import_all = None;
         let mut single_imports = Vec::new();
         for attr in &item.attrs {
@@ -1188,7 +1188,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
     /// Visit invocation in context in which it can emit a named item (possibly `macro_rules`)
     /// directly into its parent scope's module.
-    fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'a> {
+    fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
         let invoc_id = self.visit_invoc(id);
         self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
         self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
@@ -1221,7 +1221,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> {
+    fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
         let parent_scope = self.parent_scope;
         let expansion = parent_scope.expansion;
         let feed = self.r.feed(item.id);
@@ -1308,7 +1308,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
 macro_rules! method {
     ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
-        fn $visit(&mut self, node: &'b $ty) {
+        fn $visit(&mut self, node: &'a $ty) {
             if let $invoc(..) = node.kind {
                 self.visit_invoc(node.id);
             } else {
@@ -1318,12 +1318,12 @@ macro_rules! method {
     };
 }
 
-impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
     method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr);
     method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat);
     method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty);
 
-    fn visit_item(&mut self, item: &'b Item) {
+    fn visit_item(&mut self, item: &'a Item) {
         let orig_module_scope = self.parent_scope.module;
         self.parent_scope.macro_rules = match item.kind {
             ItemKind::MacroDef(..) => {
@@ -1357,7 +1357,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         self.parent_scope.module = orig_module_scope;
     }
 
-    fn visit_stmt(&mut self, stmt: &'b ast::Stmt) {
+    fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
         if let ast::StmtKind::MacCall(..) = stmt.kind {
             self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
         } else {
@@ -1365,7 +1365,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_foreign_item(&mut self, foreign_item: &'b ForeignItem) {
+    fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
         if let ForeignItemKind::MacCall(_) = foreign_item.kind {
             self.visit_invoc_in_module(foreign_item.id);
             return;
@@ -1375,7 +1375,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         visit::walk_item(self, foreign_item);
     }
 
-    fn visit_block(&mut self, block: &'b Block) {
+    fn visit_block(&mut self, block: &'a Block) {
         let orig_current_module = self.parent_scope.module;
         let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
         self.build_reduced_graph_for_block(block);
@@ -1384,7 +1384,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         self.parent_scope.macro_rules = orig_current_macro_rules_scope;
     }
 
-    fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) {
+    fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
         if let AssocItemKind::MacCall(_) = item.kind {
             match ctxt {
                 AssocCtxt::Trait => {
@@ -1440,7 +1440,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         visit::walk_assoc_item(self, item, ctxt);
     }
 
-    fn visit_attribute(&mut self, attr: &'b ast::Attribute) {
+    fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
         if !attr.is_doc_comment() && attr::is_builtin_attr(attr) {
             self.r
                 .builtin_attrs
@@ -1449,7 +1449,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         visit::walk_attribute(self, attr);
     }
 
-    fn visit_arm(&mut self, arm: &'b ast::Arm) {
+    fn visit_arm(&mut self, arm: &'a ast::Arm) {
         if arm.is_placeholder {
             self.visit_invoc(arm.id);
         } else {
@@ -1457,7 +1457,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_expr_field(&mut self, f: &'b ast::ExprField) {
+    fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
         if f.is_placeholder {
             self.visit_invoc(f.id);
         } else {
@@ -1465,7 +1465,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_pat_field(&mut self, fp: &'b ast::PatField) {
+    fn visit_pat_field(&mut self, fp: &'a ast::PatField) {
         if fp.is_placeholder {
             self.visit_invoc(fp.id);
         } else {
@@ -1473,7 +1473,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_generic_param(&mut self, param: &'b ast::GenericParam) {
+    fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
         if param.is_placeholder {
             self.visit_invoc(param.id);
         } else {
@@ -1481,7 +1481,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_param(&mut self, p: &'b ast::Param) {
+    fn visit_param(&mut self, p: &'a ast::Param) {
         if p.is_placeholder {
             self.visit_invoc(p.id);
         } else {
@@ -1489,7 +1489,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
     }
 
-    fn visit_field_def(&mut self, sf: &'b ast::FieldDef) {
+    fn visit_field_def(&mut self, sf: &'a ast::FieldDef) {
         if sf.is_placeholder {
             self.visit_invoc(sf.id);
         } else {
@@ -1501,7 +1501,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
     // Constructs the reduced graph for one variant. Variants exist in the
     // type and value namespaces.
-    fn visit_variant(&mut self, variant: &'b ast::Variant) {
+    fn visit_variant(&mut self, variant: &'a ast::Variant) {
         if variant.is_placeholder {
             self.visit_invoc_in_module(variant.id);
             return;
@@ -1542,7 +1542,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         visit::walk_variant(self, variant);
     }
 
-    fn visit_crate(&mut self, krate: &'b ast::Crate) {
+    fn visit_crate(&mut self, krate: &'a ast::Crate) {
         if krate.is_placeholder {
             self.visit_invoc_in_module(krate.id);
         } else {
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 1cee876b80f..8c434007f2c 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -52,8 +52,8 @@ impl UnusedImport {
     }
 }
 
-struct UnusedImportCheckVisitor<'a, 'b, 'tcx> {
-    r: &'a mut Resolver<'b, 'tcx>,
+struct UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
+    r: &'a mut Resolver<'ra, 'tcx>,
     /// All the (so far) unused imports, grouped path list
     unused_imports: FxIndexMap<ast::NodeId, UnusedImport>,
     extern_crate_items: Vec<ExternCrateToLint>,
@@ -78,7 +78,7 @@ struct ExternCrateToLint {
     renames: bool,
 }
 
-impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
     // We have information about whether `use` (import) items are actually
     // used now. If an import is not used at all, we signal a lint error.
     fn check_import(&mut self, id: ast::NodeId) {
@@ -212,7 +212,7 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
     fn visit_item(&mut self, item: &'a ast::Item) {
         match item.kind {
             // Ignore is_public import statements because there's no way to be sure
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 0fedb998463..6458c888431 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -12,28 +12,43 @@ use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
 use tracing::debug;
 
-use crate::{ImplTraitContext, Resolver};
+use crate::{ImplTraitContext, InvocationParent, PendingAnonConstInfo, Resolver};
 
 pub(crate) fn collect_definitions(
     resolver: &mut Resolver<'_, '_>,
     fragment: &AstFragment,
     expansion: LocalExpnId,
 ) {
-    let (parent_def, impl_trait_context, in_attr) = resolver.invocation_parents[&expansion];
-    let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr };
+    let InvocationParent { parent_def, pending_anon_const_info, impl_trait_context, in_attr } =
+        resolver.invocation_parents[&expansion];
+    let mut visitor = DefCollector {
+        resolver,
+        parent_def,
+        pending_anon_const_info,
+        expansion,
+        impl_trait_context,
+        in_attr,
+    };
     fragment.visit_with(&mut visitor);
 }
 
 /// Creates `DefId`s for nodes in the AST.
-struct DefCollector<'a, 'b, 'tcx> {
-    resolver: &'a mut Resolver<'b, 'tcx>,
+struct DefCollector<'a, 'ra, 'tcx> {
+    resolver: &'a mut Resolver<'ra, 'tcx>,
     parent_def: LocalDefId,
+    /// If we have an anon const that consists of a macro invocation, e.g. `Foo<{ m!() }>`,
+    /// we need to wait until we know what the macro expands to before we create the def for
+    /// the anon const. That's because we lower some anon consts into `hir::ConstArgKind::Path`,
+    /// which don't have defs.
+    ///
+    /// See `Self::visit_anon_const()`.
+    pending_anon_const_info: Option<PendingAnonConstInfo>,
     impl_trait_context: ImplTraitContext,
     in_attr: bool,
     expansion: LocalExpnId,
 }
 
-impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
     fn create_def(
         &mut self,
         node_id: NodeId,
@@ -111,15 +126,21 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
 
     fn visit_macro_invoc(&mut self, id: NodeId) {
         let id = id.placeholder_to_expn_id();
-        let old_parent = self
-            .resolver
-            .invocation_parents
-            .insert(id, (self.parent_def, self.impl_trait_context, self.in_attr));
+        let pending_anon_const_info = self.pending_anon_const_info.take();
+        let old_parent = self.resolver.invocation_parents.insert(
+            id,
+            InvocationParent {
+                parent_def: self.parent_def,
+                pending_anon_const_info,
+                impl_trait_context: self.impl_trait_context,
+                in_attr: self.in_attr,
+            },
+        );
         assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
     }
 }
 
-impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
+impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     fn visit_item(&mut self, i: &'a Item) {
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into, the better
@@ -326,46 +347,65 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
     }
 
     fn visit_anon_const(&mut self, constant: &'a AnonConst) {
-        if self.resolver.tcx.features().const_arg_path
-            && constant.value.is_potential_trivial_const_arg()
-        {
-            // HACK(min_generic_const_args): don't create defs for anon consts if we think they will
-            // later be turned into ConstArgKind::Path's. because this is before resolve is done, we
-            // may accidentally identify a construction of a unit struct as a param and not create a
-            // def. we'll then create a def later in ast lowering in this case. the parent of nested
-            // items will be messed up, but that's ok because there can't be any if we're just looking
-            // for bare idents.
-            visit::walk_anon_const(self, constant)
-        } else {
-            let def =
-                self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span);
-            self.with_parent(def, |this| visit::walk_anon_const(this, constant));
+        // HACK(min_generic_const_args): don't create defs for anon consts if we think they will
+        // later be turned into ConstArgKind::Path's. because this is before resolve is done, we
+        // may accidentally identify a construction of a unit struct as a param and not create a
+        // def. we'll then create a def later in ast lowering in this case. the parent of nested
+        // items will be messed up, but that's ok because there can't be any if we're just looking
+        // for bare idents.
+
+        if matches!(constant.value.maybe_unwrap_block().kind, ExprKind::MacCall(..)) {
+            // See self.pending_anon_const_info for explanation
+            self.pending_anon_const_info =
+                Some(PendingAnonConstInfo { id: constant.id, span: constant.value.span });
+            return visit::walk_anon_const(self, constant);
+        } else if constant.value.is_potential_trivial_const_arg() {
+            return visit::walk_anon_const(self, constant);
         }
+
+        let def = self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span);
+        self.with_parent(def, |this| visit::walk_anon_const(this, constant));
     }
 
     fn visit_expr(&mut self, expr: &'a Expr) {
-        let parent_def = match expr.kind {
-            ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id),
-            ExprKind::Closure(..) | ExprKind::Gen(..) => {
-                self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
-            }
-            ExprKind::ConstBlock(ref constant) => {
-                for attr in &expr.attrs {
-                    visit::walk_attribute(self, attr);
-                }
-                let def = self.create_def(
-                    constant.id,
-                    kw::Empty,
-                    DefKind::InlineConst,
-                    constant.value.span,
-                );
-                self.with_parent(def, |this| visit::walk_anon_const(this, constant));
-                return;
+        if matches!(expr.kind, ExprKind::MacCall(..)) {
+            return self.visit_macro_invoc(expr.id);
+        }
+
+        let grandparent_def = if let Some(pending_anon) = self.pending_anon_const_info.take() {
+            // See self.pending_anon_const_info for explanation
+            if !expr.is_potential_trivial_const_arg() {
+                self.create_def(pending_anon.id, kw::Empty, DefKind::AnonConst, pending_anon.span)
+            } else {
+                self.parent_def
             }
-            _ => self.parent_def,
+        } else {
+            self.parent_def
         };
 
-        self.with_parent(parent_def, |this| visit::walk_expr(this, expr));
+        self.with_parent(grandparent_def, |this| {
+            let parent_def = match expr.kind {
+                ExprKind::Closure(..) | ExprKind::Gen(..) => {
+                    this.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
+                }
+                ExprKind::ConstBlock(ref constant) => {
+                    for attr in &expr.attrs {
+                        visit::walk_attribute(this, attr);
+                    }
+                    let def = this.create_def(
+                        constant.id,
+                        kw::Empty,
+                        DefKind::InlineConst,
+                        constant.value.span,
+                    );
+                    this.with_parent(def, |this| visit::walk_anon_const(this, constant));
+                    return;
+                }
+                _ => this.parent_def,
+            };
+
+            this.with_parent(parent_def, |this| visit::walk_expr(this, expr))
+        })
     }
 
     fn visit_ty(&mut self, ty: &'a Ty) {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 182577b82c4..3b69ecee357 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -123,7 +123,7 @@ fn reduce_impl_span_to_impl_keyword(sm: &SourceMap, impl_span: Span) -> Span {
     sm.span_until_whitespace(impl_span)
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
         self.tcx.dcx()
     }
@@ -208,8 +208,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         parent: Module<'_>,
         ident: Ident,
         ns: Namespace,
-        new_binding: NameBinding<'a>,
-        old_binding: NameBinding<'a>,
+        new_binding: NameBinding<'ra>,
+        old_binding: NameBinding<'ra>,
     ) {
         // Error on the second of two conflicting names
         if old_binding.span.lo() > new_binding.span.lo() {
@@ -531,7 +531,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     pub(crate) fn add_module_candidates(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         names: &mut Vec<TypoSuggestion>,
         filter_fn: &impl Fn(Res) -> bool,
         ctxt: Option<SyntaxContext>,
@@ -553,7 +553,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn report_error(
         &mut self,
         span: Span,
-        resolution_error: ResolutionError<'a>,
+        resolution_error: ResolutionError<'ra>,
     ) -> ErrorGuaranteed {
         self.into_struct_error(span, resolution_error).emit()
     }
@@ -561,7 +561,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn into_struct_error(
         &mut self,
         span: Span,
-        resolution_error: ResolutionError<'a>,
+        resolution_error: ResolutionError<'ra>,
     ) -> Diag<'_> {
         match resolution_error {
             ResolutionError::GenericParamsFromOuterItem(
@@ -1020,8 +1020,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// Lookup typo candidate in scope for a macro or import.
     fn early_lookup_typo_candidate(
         &mut self,
-        scope_set: ScopeSet<'a>,
-        parent_scope: &ParentScope<'a>,
+        scope_set: ScopeSet<'ra>,
+        parent_scope: &ParentScope<'ra>,
         ident: Ident,
         filter_fn: &impl Fn(Res) -> bool,
     ) -> Option<TypoSuggestion> {
@@ -1156,8 +1156,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         lookup_ident: Ident,
         namespace: Namespace,
-        parent_scope: &ParentScope<'a>,
-        start_module: Module<'a>,
+        parent_scope: &ParentScope<'ra>,
+        start_module: Module<'ra>,
         crate_path: ThinVec<ast::PathSegment>,
         filter_fn: FilterFn,
     ) -> Vec<ImportSuggestion>
@@ -1233,64 +1233,63 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     && ns == namespace
                     && in_module != parent_scope.module
                     && !ident.span.normalize_to_macros_2_0().from_expansion()
+                    && filter_fn(res)
                 {
-                    if filter_fn(res) {
-                        // create the path
-                        let mut segms = if lookup_ident.span.at_least_rust_2018() {
-                            // crate-local absolute paths start with `crate::` in edition 2018
-                            // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660)
-                            crate_path.clone()
-                        } else {
-                            ThinVec::new()
-                        };
-                        segms.append(&mut path_segments.clone());
+                    // create the path
+                    let mut segms = if lookup_ident.span.at_least_rust_2018() {
+                        // crate-local absolute paths start with `crate::` in edition 2018
+                        // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660)
+                        crate_path.clone()
+                    } else {
+                        ThinVec::new()
+                    };
+                    segms.append(&mut path_segments.clone());
 
-                        segms.push(ast::PathSegment::from_ident(ident));
-                        let path = Path { span: name_binding.span, segments: segms, tokens: None };
+                    segms.push(ast::PathSegment::from_ident(ident));
+                    let path = Path { span: name_binding.span, segments: segms, tokens: None };
 
-                        if child_accessible {
-                            // Remove invisible match if exists
-                            if let Some(idx) = candidates
-                                .iter()
-                                .position(|v: &ImportSuggestion| v.did == did && !v.accessible)
-                            {
-                                candidates.remove(idx);
-                            }
+                    if child_accessible {
+                        // Remove invisible match if exists
+                        if let Some(idx) = candidates
+                            .iter()
+                            .position(|v: &ImportSuggestion| v.did == did && !v.accessible)
+                        {
+                            candidates.remove(idx);
                         }
+                    }
 
-                        if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
-                            // See if we're recommending TryFrom, TryInto, or FromIterator and add
-                            // a note about editions
-                            let note = if let Some(did) = did {
-                                let requires_note = !did.is_local()
-                                    && this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any(
-                                        |attr| {
-                                            [sym::TryInto, sym::TryFrom, sym::FromIterator]
-                                                .map(|x| Some(x))
-                                                .contains(&attr.value_str())
-                                        },
-                                    );
-
-                                requires_note.then(|| {
-                                    format!(
-                                        "'{}' is included in the prelude starting in Edition 2021",
-                                        path_names_to_string(&path)
-                                    )
-                                })
-                            } else {
-                                None
-                            };
-
-                            candidates.push(ImportSuggestion {
-                                did,
-                                descr: res.descr(),
-                                path,
-                                accessible: child_accessible,
-                                doc_visible: child_doc_visible,
-                                note,
-                                via_import,
-                            });
-                        }
+                    if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
+                        // See if we're recommending TryFrom, TryInto, or FromIterator and add
+                        // a note about editions
+                        let note = if let Some(did) = did {
+                            let requires_note = !did.is_local()
+                                && this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any(
+                                    |attr| {
+                                        [sym::TryInto, sym::TryFrom, sym::FromIterator]
+                                            .map(|x| Some(x))
+                                            .contains(&attr.value_str())
+                                    },
+                                );
+
+                            requires_note.then(|| {
+                                format!(
+                                    "'{}' is included in the prelude starting in Edition 2021",
+                                    path_names_to_string(&path)
+                                )
+                            })
+                        } else {
+                            None
+                        };
+
+                        candidates.push(ImportSuggestion {
+                            did,
+                            descr: res.descr(),
+                            path,
+                            accessible: child_accessible,
+                            doc_visible: child_doc_visible,
+                            note,
+                            via_import,
+                        });
                     }
                 }
 
@@ -1343,7 +1342,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         lookup_ident: Ident,
         namespace: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         filter_fn: FilterFn,
     ) -> Vec<ImportSuggestion>
     where
@@ -1421,7 +1420,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         err: &mut Diag<'_>,
         macro_kind: MacroKind,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         ident: Ident,
         krate: &Crate,
     ) {
@@ -1749,7 +1748,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         None
     }
 
-    fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'a>) {
+    fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
         let PrivacyError { ident, binding, outermost_res, parent_scope, single_nested, dedup_span } =
             *privacy_error;
 
@@ -1954,7 +1953,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn find_similarly_named_module_or_crate(
         &mut self,
         ident: Symbol,
-        current_module: Module<'a>,
+        current_module: Module<'ra>,
     ) -> Option<Symbol> {
         let mut candidates = self
             .extern_prelude
@@ -1982,11 +1981,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
-        parent_scope: &ParentScope<'a>,
-        ribs: Option<&PerNS<Vec<Rib<'a>>>>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-        module: Option<ModuleOrUniformRoot<'a>>,
+        parent_scope: &ParentScope<'ra>,
+        ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+        module: Option<ModuleOrUniformRoot<'ra>>,
         failed_segment_idx: usize,
         ident: Ident,
     ) -> (String, Option<Suggestion>) {
@@ -2228,7 +2227,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         span: Span,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         debug!("make_path_suggestion: span={:?} path={:?}", span, path);
 
@@ -2263,7 +2262,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn make_missing_self_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = kw::SelfLower;
@@ -2282,7 +2281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn make_missing_crate_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Crate;
@@ -2313,7 +2312,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn make_missing_super_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = kw::Super;
@@ -2335,7 +2334,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn make_external_crate_suggestion(
         &mut self,
         mut path: Vec<Segment>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         if path[1].ident.span.is_rust_2015() {
             return None;
@@ -2378,8 +2377,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// ```
     pub(crate) fn check_for_module_export_macro(
         &mut self,
-        import: Import<'a>,
-        module: ModuleOrUniformRoot<'a>,
+        import: Import<'ra>,
+        module: ModuleOrUniformRoot<'ra>,
         ident: Ident,
     ) -> Option<(Option<Suggestion>, Option<String>)> {
         let ModuleOrUniformRoot::Module(mut crate_module) = module else {
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index 5ee495da2d9..c91eed0e39b 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -11,9 +11,9 @@ use tracing::info;
 use crate::{NameBinding, NameBindingKind, Resolver};
 
 #[derive(Clone, Copy)]
-enum ParentId<'a> {
+enum ParentId<'ra> {
     Def(LocalDefId),
-    Import(NameBinding<'a>),
+    Import(NameBinding<'ra>),
 }
 
 impl ParentId<'_> {
@@ -25,13 +25,13 @@ impl ParentId<'_> {
     }
 }
 
-pub(crate) struct EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
-    r: &'r mut Resolver<'a, 'tcx>,
+pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
+    r: &'a mut Resolver<'ra, 'tcx>,
     def_effective_visibilities: EffectiveVisibilities,
     /// While walking import chains we need to track effective visibilities per-binding, and def id
     /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
     /// bindings can correspond to a single def id in imports. So we keep a separate table.
-    import_effective_visibilities: EffectiveVisibilities<NameBinding<'a>>,
+    import_effective_visibilities: EffectiveVisibilities<NameBinding<'ra>>,
     // It's possible to recalculate this at any point, but it's relatively expensive.
     current_private_vis: Visibility,
     changed: bool,
@@ -63,14 +63,14 @@ impl Resolver<'_, '_> {
     }
 }
 
-impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
+impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
     /// Fills the `Resolver::effective_visibilities` table with public & exported items
     /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
     /// need access to a TyCtxt for that. Returns the set of ambiguous re-exports.
     pub(crate) fn compute_effective_visibilities<'c>(
-        r: &'r mut Resolver<'a, 'tcx>,
+        r: &'a mut Resolver<'ra, 'tcx>,
         krate: &'c Crate,
-    ) -> FxHashSet<NameBinding<'a>> {
+    ) -> FxHashSet<NameBinding<'ra>> {
         let mut visitor = EffectiveVisibilitiesVisitor {
             r,
             def_effective_visibilities: Default::default(),
@@ -127,7 +127,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
                 // leading to it into the table. They are used by the `ambiguous_glob_reexports`
                 // lint. For all bindings added to the table this way `is_ambiguity` returns true.
                 let is_ambiguity =
-                    |binding: NameBinding<'a>, warn: bool| binding.ambiguity.is_some() && !warn;
+                    |binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
                 let mut parent_id = ParentId::Def(module_id);
                 let mut warn_ambiguity = binding.warn_ambiguity;
                 while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
@@ -153,7 +153,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
         }
     }
 
-    fn effective_vis_or_private(&mut self, parent_id: ParentId<'a>) -> EffectiveVisibility {
+    fn effective_vis_or_private(&mut self, parent_id: ParentId<'ra>) -> EffectiveVisibility {
         // Private nodes are only added to the table for caching, they could be added or removed at
         // any moment without consequences, so we don't set `changed` to true when adding them.
         *match parent_id {
@@ -190,7 +190,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
         }
     }
 
-    fn update_import(&mut self, binding: NameBinding<'a>, parent_id: ParentId<'a>) {
+    fn update_import(&mut self, binding: NameBinding<'ra>, parent_id: ParentId<'ra>) {
         let nominal_vis = binding.vis.expect_local();
         let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
         let inherited_eff_vis = self.effective_vis_or_private(parent_id);
@@ -205,7 +205,12 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
         );
     }
 
-    fn update_def(&mut self, def_id: LocalDefId, nominal_vis: Visibility, parent_id: ParentId<'a>) {
+    fn update_def(
+        &mut self,
+        def_id: LocalDefId,
+        nominal_vis: Visibility,
+        parent_id: ParentId<'ra>,
+    ) {
         let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
         let inherited_eff_vis = self.effective_vis_or_private(parent_id);
         let tcx = self.r.tcx;
@@ -224,8 +229,8 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
     }
 }
 
-impl<'r, 'ast, 'tcx> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r, 'tcx> {
-    fn visit_item(&mut self, item: &'ast ast::Item) {
+impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
+    fn visit_item(&mut self, item: &'a ast::Item) {
         let def_id = self.r.local_def_id(item.id);
         // Update effective visibilities of nested items.
         // If it's a mod, also make the visitor walk all of its items
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 87f8e51f282..61df051ec1e 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -38,16 +38,16 @@ impl From<UsePrelude> for bool {
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     /// A generic scope visitor.
     /// Visits scopes in order to resolve some identifier in them or perform other actions.
     /// If the callback returns `Some` result, we stop visiting scopes and return it.
     pub(crate) fn visit_scopes<T>(
         &mut self,
-        scope_set: ScopeSet<'a>,
-        parent_scope: &ParentScope<'a>,
+        scope_set: ScopeSet<'ra>,
+        parent_scope: &ParentScope<'ra>,
         ctxt: SyntaxContext,
-        mut visitor: impl FnMut(&mut Self, Scope<'a>, UsePrelude, SyntaxContext) -> Option<T>,
+        mut visitor: impl FnMut(&mut Self, Scope<'ra>, UsePrelude, SyntaxContext) -> Option<T>,
     ) -> Option<T> {
         // General principles:
         // 1. Not controlled (user-defined) names should have higher priority than controlled names
@@ -218,10 +218,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn hygienic_lexical_parent(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         ctxt: &mut SyntaxContext,
         derive_fallback_lint_id: Option<NodeId>,
-    ) -> Option<(Module<'a>, Option<NodeId>)> {
+    ) -> Option<(Module<'ra>, Option<NodeId>)> {
         if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
             return Some((self.expn_def_scope(ctxt.remove_mark()), None));
         }
@@ -286,11 +286,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         mut ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ribs: &[Rib<'a>],
-        ignore_binding: Option<NameBinding<'a>>,
-    ) -> Option<LexicalScopeBinding<'a>> {
+        ribs: &[Rib<'ra>],
+        ignore_binding: Option<NameBinding<'ra>>,
+    ) -> Option<LexicalScopeBinding<'ra>> {
         assert!(ns == TypeNS || ns == ValueNS);
         let orig_ident = ident;
         if ident.name == kw::Empty {
@@ -381,13 +381,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     pub(crate) fn early_resolve_ident_in_lexical_scope(
         &mut self,
         orig_ident: Ident,
-        scope_set: ScopeSet<'a>,
-        parent_scope: &ParentScope<'a>,
+        scope_set: ScopeSet<'ra>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
         force: bool,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, Determinacy> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, Determinacy> {
         bitflags::bitflags! {
             #[derive(Clone, Copy)]
             struct Flags: u8 {
@@ -742,12 +742,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     pub(crate) fn maybe_resolve_ident_in_module(
         &mut self,
-        module: ModuleOrUniformRoot<'a>,
+        module: ModuleOrUniformRoot<'ra>,
         ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, Determinacy> {
+        parent_scope: &ParentScope<'ra>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, Determinacy> {
         self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None, ignore_import)
             .map_err(|(determinacy, _)| determinacy)
     }
@@ -755,14 +755,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     pub(crate) fn resolve_ident_in_module(
         &mut self,
-        module: ModuleOrUniformRoot<'a>,
+        module: ModuleOrUniformRoot<'ra>,
         ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, Determinacy> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, Determinacy> {
         self.resolve_ident_in_module_ext(
             module,
             ident,
@@ -778,14 +778,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_ext(
         &mut self,
-        module: ModuleOrUniformRoot<'a>,
+        module: ModuleOrUniformRoot<'ra>,
         mut ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
         let tmp_parent_scope;
         let mut adjusted_parent_scope = parent_scope;
         match module {
@@ -818,14 +818,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted(
         &mut self,
-        module: ModuleOrUniformRoot<'a>,
+        module: ModuleOrUniformRoot<'ra>,
         ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, Determinacy> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, Determinacy> {
         self.resolve_ident_in_module_unadjusted_ext(
             module,
             ident,
@@ -844,17 +844,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn resolve_ident_in_module_unadjusted_ext(
         &mut self,
-        module: ModuleOrUniformRoot<'a>,
+        module: ModuleOrUniformRoot<'ra>,
         ident: Ident,
         ns: Namespace,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         restricted_shadowing: bool,
         finalize: Option<Finalize>,
         // This binding should be ignored during in-module resolution, so that we don't get
         // "self-confirming" import resolutions during import validation and checking.
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
         let module = match module {
             ModuleOrUniformRoot::Module(module) => module,
             ModuleOrUniformRoot::CrateRootAndExternPrelude => {
@@ -958,19 +958,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 });
             }
 
-            if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT {
-                if let NameBindingKind::Import { import, .. } = binding.kind
-                    && matches!(import.kind, ImportKind::MacroExport)
-                {
-                    self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
-                }
+            if !restricted_shadowing
+                && binding.expansion != LocalExpnId::ROOT
+                && let NameBindingKind::Import { import, .. } = binding.kind
+                && matches!(import.kind, ImportKind::MacroExport)
+            {
+                self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
             }
 
             self.record_use(ident, binding, used);
             return Ok(binding);
         }
 
-        let check_usable = |this: &mut Self, binding: NameBinding<'a>| {
+        let check_usable = |this: &mut Self, binding: NameBinding<'ra>| {
             let usable = this.is_accessible_from(binding.vis, parent_scope.module);
             if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
         };
@@ -1151,7 +1151,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         mut res: Res,
         finalize: Option<Span>,
         original_rib_ident_def: Ident,
-        all_ribs: &[Rib<'a>],
+        all_ribs: &[Rib<'ra>],
     ) -> Res {
         debug!("validate_res_from_ribs({:?})", res);
         let ribs = &all_ribs[rib_index + 1..];
@@ -1436,9 +1436,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
-        parent_scope: &ParentScope<'a>,
-        ignore_import: Option<Import<'a>>,
-    ) -> PathResult<'a> {
+        parent_scope: &ParentScope<'ra>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> PathResult<'ra> {
         self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
     }
 
@@ -1447,11 +1447,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> PathResult<'a> {
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> PathResult<'ra> {
         self.resolve_path_with_ribs(
             path,
             opt_ns,
@@ -1467,12 +1467,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         finalize: Option<Finalize>,
-        ribs: Option<&PerNS<Vec<Rib<'a>>>>,
-        ignore_binding: Option<NameBinding<'a>>,
-        ignore_import: Option<Import<'a>>,
-    ) -> PathResult<'a> {
+        ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
+        ignore_binding: Option<NameBinding<'ra>>,
+        ignore_import: Option<Import<'ra>>,
+    ) -> PathResult<'ra> {
         let mut module = None;
         let mut allow_super = true;
         let mut second_binding = None;
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 42171edf757..67ee377fd54 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -43,7 +43,7 @@ type Res = def::Res<NodeId>;
 
 /// Contains data for specific kinds of imports.
 #[derive(Clone)]
-pub(crate) enum ImportKind<'a> {
+pub(crate) enum ImportKind<'ra> {
     Single {
         /// `source` in `use prefix::source as target`.
         source: Ident,
@@ -51,9 +51,9 @@ pub(crate) enum ImportKind<'a> {
         /// It will directly use `source` when the format is `use prefix::source`.
         target: Ident,
         /// Bindings to which `source` refers to.
-        source_bindings: PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
+        source_bindings: PerNS<Cell<Result<NameBinding<'ra>, Determinacy>>>,
         /// Bindings introduced by `target`.
-        target_bindings: PerNS<Cell<Option<NameBinding<'a>>>>,
+        target_bindings: PerNS<Cell<Option<NameBinding<'ra>>>>,
         /// `true` for `...::{self [as target]}` imports, `false` otherwise.
         type_ns_only: bool,
         /// Did this import result from a nested import? ie. `use foo::{bar, baz};`
@@ -93,7 +93,7 @@ pub(crate) enum ImportKind<'a> {
 
 /// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
 /// contain `Cell`s which can introduce infinite loops while printing.
-impl<'a> std::fmt::Debug for ImportKind<'a> {
+impl<'ra> std::fmt::Debug for ImportKind<'ra> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         use ImportKind::*;
         match self {
@@ -142,8 +142,8 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
 
 /// One import.
 #[derive(Debug, Clone)]
-pub(crate) struct ImportData<'a> {
-    pub kind: ImportKind<'a>,
+pub(crate) struct ImportData<'ra> {
+    pub kind: ImportKind<'ra>,
 
     /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
     /// (if it exists) except in the case of "nested" use trees, in which case
@@ -171,18 +171,18 @@ pub(crate) struct ImportData<'a> {
     /// Span of the *root* use tree (see `root_id`).
     pub root_span: Span,
 
-    pub parent_scope: ParentScope<'a>,
+    pub parent_scope: ParentScope<'ra>,
     pub module_path: Vec<Segment>,
     /// The resolution of `module_path`.
-    pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
+    pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
     pub vis: ty::Visibility,
 }
 
 /// All imports are unique and allocated on a same arena,
 /// so we can use referential equality to compare them.
-pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>;
+pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>;
 
-impl<'a> ImportData<'a> {
+impl<'ra> ImportData<'ra> {
     pub(crate) fn is_glob(&self) -> bool {
         matches!(self.kind, ImportKind::Glob { .. })
     }
@@ -217,18 +217,18 @@ impl<'a> ImportData<'a> {
 
 /// Records information about the resolution of a name in a namespace of a module.
 #[derive(Clone, Default, Debug)]
-pub(crate) struct NameResolution<'a> {
+pub(crate) struct NameResolution<'ra> {
     /// Single imports that may define the name in the namespace.
     /// Imports are arena-allocated, so it's ok to use pointers as keys.
-    pub single_imports: FxHashSet<Import<'a>>,
+    pub single_imports: FxHashSet<Import<'ra>>,
     /// The least shadowable known binding for this name, or None if there are no known bindings.
-    pub binding: Option<NameBinding<'a>>,
-    pub shadowed_glob: Option<NameBinding<'a>>,
+    pub binding: Option<NameBinding<'ra>>,
+    pub shadowed_glob: Option<NameBinding<'ra>>,
 }
 
-impl<'a> NameResolution<'a> {
+impl<'ra> NameResolution<'ra> {
     /// Returns the binding for the name if it is known or None if it not known.
-    pub(crate) fn binding(&self) -> Option<NameBinding<'a>> {
+    pub(crate) fn binding(&self) -> Option<NameBinding<'ra>> {
         self.binding.and_then(|binding| {
             if !binding.is_glob_import() || self.single_imports.is_empty() {
                 Some(binding)
@@ -270,10 +270,14 @@ fn pub_use_of_private_extern_crate_hack(
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     /// Given a binding and an import that resolves to it,
     /// return the corresponding binding defined by the import.
-    pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> {
+    pub(crate) fn import(
+        &self,
+        binding: NameBinding<'ra>,
+        import: Import<'ra>,
+    ) -> NameBinding<'ra> {
         let import_vis = import.vis.to_def_id();
         let vis = if binding.vis.is_at_least(import_vis, self.tcx)
             || pub_use_of_private_extern_crate_hack(import, binding).is_some()
@@ -305,11 +309,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// `update` indicates if the definition is a redefinition of an existing binding.
     pub(crate) fn try_define(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         key: BindingKey,
-        binding: NameBinding<'a>,
+        binding: NameBinding<'ra>,
         warn_ambiguity: bool,
-    ) -> Result<(), NameBinding<'a>> {
+    ) -> Result<(), NameBinding<'ra>> {
         let res = binding.res();
         self.check_reserved_macro_name(key.ident, res);
         self.set_binding_parent_module(binding, module);
@@ -394,16 +398,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn new_ambiguity_binding(
         &self,
         ambiguity_kind: AmbiguityKind,
-        primary_binding: NameBinding<'a>,
-        secondary_binding: NameBinding<'a>,
+        primary_binding: NameBinding<'ra>,
+        secondary_binding: NameBinding<'ra>,
         warn_ambiguity: bool,
-    ) -> NameBinding<'a> {
+    ) -> NameBinding<'ra> {
         let ambiguity = Some((secondary_binding, ambiguity_kind));
         let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
         self.arenas.alloc_name_binding(data)
     }
 
-    fn new_warn_ambiguity_binding(&self, binding: NameBinding<'a>) -> NameBinding<'a> {
+    fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> {
         assert!(binding.is_ambiguity_recursive());
         self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
     }
@@ -412,13 +416,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     // If the resolution becomes a success, define it in the module's glob importers.
     fn update_resolution<T, F>(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         key: BindingKey,
         warn_ambiguity: bool,
         f: F,
     ) -> T
     where
-        F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
+        F: FnOnce(&mut Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
     {
         // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
         // during which the resolution might end up getting re-defined via a glob cycle.
@@ -466,7 +470,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
     // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
-    fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) {
+    fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) {
         if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
             if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
             {
@@ -599,7 +603,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     pub(crate) fn check_hidden_glob_reexports(
         &mut self,
-        exported_ambiguities: FxHashSet<NameBinding<'a>>,
+        exported_ambiguities: FxHashSet<NameBinding<'ra>>,
     ) {
         for module in self.arenas.local_modules().iter() {
             for (key, resolution) in self.resolutions(*module).borrow().iter() {
@@ -759,7 +763,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     ///
     /// Meanwhile, if resolve successful, the resolved bindings are written
     /// into the module.
-    fn resolve_import(&mut self, import: Import<'a>) -> usize {
+    fn resolve_import(&mut self, import: Import<'ra>) -> usize {
         debug!(
             "(resolving import for module) resolving import `{}::...` in `{}`",
             Segment::names_to_string(&import.module_path),
@@ -847,7 +851,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     ///
     /// Optionally returns an unresolved import error. This error is buffered and used to
     /// consolidate multiple unresolved import errors into a single diagnostic.
-    fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
+    fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> {
         let ignore_binding = match &import.kind {
             ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
             _ => None,
@@ -1256,28 +1260,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         extern_crate_span: self.tcx.source_span(self.local_def_id(extern_crate_id)),
                     },
                 );
+            } else if ns == TypeNS {
+                let err = if crate_private_reexport {
+                    self.dcx()
+                        .create_err(CannotBeReexportedCratePublicNS { span: import.span, ident })
+                } else {
+                    self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
+                };
+                err.emit();
             } else {
-                if ns == TypeNS {
-                    let err = if crate_private_reexport {
-                        self.dcx().create_err(CannotBeReexportedCratePublicNS {
-                            span: import.span,
-                            ident,
-                        })
-                    } else {
-                        self.dcx()
-                            .create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
-                    };
-                    err.emit();
+                let mut err = if crate_private_reexport {
+                    self.dcx()
+                        .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
                 } else {
-                    let mut err = if crate_private_reexport {
-                        self.dcx()
-                            .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
-                    } else {
-                        self.dcx()
-                            .create_err(CannotBeReexportedPrivate { span: import.span, ident })
-                    };
+                    self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident })
+                };
 
-                    match binding.kind {
+                match binding.kind {
                         NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
                             // exclude decl_macro
                             if self.get_macro_by_def_id(def_id).macro_rules =>
@@ -1293,8 +1292,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             });
                         }
                     }
-                    err.emit();
-                }
+                err.emit();
             }
         }
 
@@ -1323,7 +1321,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         None
     }
 
-    pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'a>) -> bool {
+    pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
         // This function is only called for single imports.
         let ImportKind::Single {
             source, target, ref source_bindings, ref target_bindings, id, ..
@@ -1398,7 +1396,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         false
     }
 
-    fn resolve_glob_import(&mut self, import: Import<'a>) {
+    fn resolve_glob_import(&mut self, import: Import<'ra>) {
         // This function is only called for glob imports.
         let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
 
@@ -1458,7 +1456,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     // Miscellaneous post-processing, including recording re-exports,
     // reporting conflicts, and reporting unresolved imports.
-    fn finalize_resolutions_in(&mut self, module: Module<'a>) {
+    fn finalize_resolutions_in(&mut self, module: Module<'ra>) {
         // Since import resolution is finished, globs will not define any more names.
         *module.globs.borrow_mut() = Vec::new();
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 40a6ac70bfd..0aa351cad40 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -172,7 +172,7 @@ enum RecordPartialRes {
 /// The rib kind restricts certain accesses,
 /// e.g. to a `Res::Local` of an outer item.
 #[derive(Copy, Clone, Debug)]
-pub(crate) enum RibKind<'a> {
+pub(crate) enum RibKind<'ra> {
     /// No restriction needs to be applied.
     Normal,
 
@@ -195,7 +195,7 @@ pub(crate) enum RibKind<'a> {
     ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
 
     /// We passed through a module.
-    Module(Module<'a>),
+    Module(Module<'ra>),
 
     /// We passed through a `macro_rules!` statement
     MacroDefinition(DefId),
@@ -260,13 +260,13 @@ impl RibKind<'_> {
 /// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
-pub(crate) struct Rib<'a, R = Res> {
+pub(crate) struct Rib<'ra, R = Res> {
     pub bindings: IdentMap<R>,
-    pub kind: RibKind<'a>,
+    pub kind: RibKind<'ra>,
 }
 
-impl<'a, R> Rib<'a, R> {
-    fn new(kind: RibKind<'a>) -> Rib<'a, R> {
+impl<'ra, R> Rib<'ra, R> {
+    fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {
         Rib { bindings: Default::default(), kind }
     }
 }
@@ -584,8 +584,8 @@ impl MaybeExported<'_> {
 
 /// Used for recording UnnecessaryQualification.
 #[derive(Debug)]
-pub(crate) struct UnnecessaryQualification<'a> {
-    pub binding: LexicalScopeBinding<'a>,
+pub(crate) struct UnnecessaryQualification<'ra> {
+    pub binding: LexicalScopeBinding<'ra>,
     pub node_id: NodeId,
     pub path_span: Span,
     pub removal_span: Span,
@@ -659,20 +659,20 @@ struct DiagMetadata<'ast> {
     current_elision_failures: Vec<MissingLifetime>,
 }
 
-struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
-    r: &'b mut Resolver<'a, 'tcx>,
+struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
+    r: &'a mut Resolver<'ra, 'tcx>,
 
     /// The module that represents the current item scope.
-    parent_scope: ParentScope<'a>,
+    parent_scope: ParentScope<'ra>,
 
     /// The current set of local scopes for types and values.
-    ribs: PerNS<Vec<Rib<'a>>>,
+    ribs: PerNS<Vec<Rib<'ra>>>,
 
     /// Previous popped `rib`, only used for diagnostic.
-    last_block_rib: Option<Rib<'a>>,
+    last_block_rib: Option<Rib<'ra>>,
 
     /// The current set of local scopes, for labels.
-    label_ribs: Vec<Rib<'a, NodeId>>,
+    label_ribs: Vec<Rib<'ra, NodeId>>,
 
     /// The current set of local scopes for lifetimes.
     lifetime_ribs: Vec<LifetimeRib>,
@@ -685,7 +685,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
 
     /// The trait that the current context can refer to.
-    current_trait_ref: Option<(Module<'a>, TraitRef)>,
+    current_trait_ref: Option<(Module<'ra>, TraitRef)>,
 
     /// Fields used to add information to diagnostic errors.
     diag_metadata: Box<DiagMetadata<'ast>>,
@@ -702,7 +702,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 }
 
 /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
-impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
+impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
     fn visit_attribute(&mut self, _: &'ast Attribute) {
         // We do not want to resolve expressions that appear in attributes,
         // as they do not correspond to actual code.
@@ -1316,8 +1316,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
     }
 }
 
-impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
-    fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
+impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
+    fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         // During late resolution we only track the module component of the parent scope,
         // although it may be useful to track other components as well for diagnostics.
         let graph_root = resolver.graph_root;
@@ -1347,7 +1347,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         &mut self,
         ident: Ident,
         ns: Namespace,
-    ) -> Option<LexicalScopeBinding<'a>> {
+    ) -> Option<LexicalScopeBinding<'ra>> {
         self.r.resolve_ident_in_lexical_scope(
             ident,
             ns,
@@ -1363,8 +1363,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         ident: Ident,
         ns: Namespace,
         finalize: Option<Finalize>,
-        ignore_binding: Option<NameBinding<'a>>,
-    ) -> Option<LexicalScopeBinding<'a>> {
+        ignore_binding: Option<NameBinding<'ra>>,
+    ) -> Option<LexicalScopeBinding<'ra>> {
         self.r.resolve_ident_in_lexical_scope(
             ident,
             ns,
@@ -1380,7 +1380,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         path: &[Segment],
         opt_ns: Option<Namespace>, // `None` indicates a module path in import
         finalize: Option<Finalize>,
-    ) -> PathResult<'a> {
+    ) -> PathResult<'ra> {
         self.r.resolve_path_with_ribs(
             path,
             opt_ns,
@@ -1414,7 +1414,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     fn with_rib<T>(
         &mut self,
         ns: Namespace,
-        kind: RibKind<'a>,
+        kind: RibKind<'ra>,
         work: impl FnOnce(&mut Self) -> T,
     ) -> T {
         self.ribs[ns].push(Rib::new(kind));
@@ -2266,14 +2266,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         /// Visits a type to find all the &references, and determines the
         /// set of lifetimes for all of those references where the referent
         /// contains Self.
-        struct FindReferenceVisitor<'r, 'a, 'tcx> {
-            r: &'r Resolver<'a, 'tcx>,
+        struct FindReferenceVisitor<'a, 'ra, 'tcx> {
+            r: &'a Resolver<'ra, 'tcx>,
             impl_self: Option<Res>,
             lifetime: Set1<LifetimeRes>,
         }
 
-        impl<'a> Visitor<'a> for FindReferenceVisitor<'_, '_, '_> {
-            fn visit_ty(&mut self, ty: &'a Ty) {
+        impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
+            fn visit_ty(&mut self, ty: &'ra Ty) {
                 trace!("FindReferenceVisitor considering ty={:?}", ty);
                 if let TyKind::Ref(lt, _) = ty.kind {
                     // See if anything inside the &thing contains Self
@@ -2299,13 +2299,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             // A type may have an expression as a const generic argument.
             // We do not want to recurse into those.
-            fn visit_expr(&mut self, _: &'a Expr) {}
+            fn visit_expr(&mut self, _: &'ra Expr) {}
         }
 
         /// Visitor which checks the referent of a &Thing to see if the
         /// Thing contains Self
-        struct SelfVisitor<'r, 'a, 'tcx> {
-            r: &'r Resolver<'a, 'tcx>,
+        struct SelfVisitor<'a, 'ra, 'tcx> {
+            r: &'a Resolver<'ra, 'tcx>,
             impl_self: Option<Res>,
             self_found: bool,
         }
@@ -2327,8 +2327,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
         }
 
-        impl<'a> Visitor<'a> for SelfVisitor<'_, '_, '_> {
-            fn visit_ty(&mut self, ty: &'a Ty) {
+        impl<'ra> Visitor<'ra> for SelfVisitor<'_, '_, '_> {
+            fn visit_ty(&mut self, ty: &'ra Ty) {
                 trace!("SelfVisitor considering ty={:?}", ty);
                 if self.is_self_ty(ty) {
                     trace!("SelfVisitor found Self");
@@ -2339,7 +2339,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             // A type may have an expression as a const generic argument.
             // We do not want to recurse into those.
-            fn visit_expr(&mut self, _: &'a Expr) {}
+            fn visit_expr(&mut self, _: &'ra Expr) {}
         }
 
         let impl_self = self
@@ -2371,7 +2371,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
     /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
     /// label and reports an error if the label is not found or is unreachable.
-    fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> {
+    fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'ra>> {
         let mut suggestion = None;
 
         for i in (0..self.label_ribs.len()).rev() {
@@ -2712,7 +2712,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     fn with_generic_param_rib<'c, F>(
         &'c mut self,
         params: &'c [GenericParam],
-        kind: RibKind<'a>,
+        kind: RibKind<'ra>,
         lifetime_kind: LifetimeRibKind,
         f: F,
     ) where
@@ -2878,7 +2878,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
     }
 
-    fn with_label_rib(&mut self, kind: RibKind<'a>, f: impl FnOnce(&mut Self)) {
+    fn with_label_rib(&mut self, kind: RibKind<'ra>, f: impl FnOnce(&mut Self)) {
         self.label_ribs.push(Rib::new(kind));
         f(self);
         self.label_ribs.pop();
@@ -3306,7 +3306,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         seen_trait_items: &mut FxHashMap<DefId, Span>,
         err: F,
     ) where
-        F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'a>,
+        F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'ra>,
     {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         let Some((module, _)) = self.current_trait_ref else {
@@ -4010,101 +4010,102 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // about possible missing imports.
         //
         // Similar thing, for types, happens in `report_errors` above.
-        let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| {
-            // Before we start looking for candidates, we have to get our hands
-            // on the type user is trying to perform invocation on; basically:
-            // we're transforming `HashMap::new` into just `HashMap`.
-            let (following_seg, prefix_path) = match path.split_last() {
-                Some((last, path)) if !path.is_empty() => (Some(last), path),
-                _ => return Some(parent_err),
-            };
+        let report_errors_for_call =
+            |this: &mut Self, parent_err: Spanned<ResolutionError<'ra>>| {
+                // Before we start looking for candidates, we have to get our hands
+                // on the type user is trying to perform invocation on; basically:
+                // we're transforming `HashMap::new` into just `HashMap`.
+                let (following_seg, prefix_path) = match path.split_last() {
+                    Some((last, path)) if !path.is_empty() => (Some(last), path),
+                    _ => return Some(parent_err),
+                };
 
-            let (mut err, candidates) = this.smart_resolve_report_errors(
-                prefix_path,
-                following_seg,
-                path_span,
-                PathSource::Type,
-                None,
-            );
+                let (mut err, candidates) = this.smart_resolve_report_errors(
+                    prefix_path,
+                    following_seg,
+                    path_span,
+                    PathSource::Type,
+                    None,
+                );
 
-            // There are two different error messages user might receive at
-            // this point:
-            // - E0412 cannot find type `{}` in this scope
-            // - E0433 failed to resolve: use of undeclared type or module `{}`
-            //
-            // The first one is emitted for paths in type-position, and the
-            // latter one - for paths in expression-position.
-            //
-            // Thus (since we're in expression-position at this point), not to
-            // confuse the user, we want to keep the *message* from E0433 (so
-            // `parent_err`), but we want *hints* from E0412 (so `err`).
-            //
-            // And that's what happens below - we're just mixing both messages
-            // into a single one.
-            let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
-
-            // overwrite all properties with the parent's error message
-            err.messages = take(&mut parent_err.messages);
-            err.code = take(&mut parent_err.code);
-            swap(&mut err.span, &mut parent_err.span);
-            err.children = take(&mut parent_err.children);
-            err.sort_span = parent_err.sort_span;
-            err.is_lint = parent_err.is_lint.clone();
-
-            // merge the parent's suggestions with the typo suggestions
-            fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
-                match res1 {
-                    Ok(vec1) => match res2 {
-                        Ok(mut vec2) => vec1.append(&mut vec2),
-                        Err(e) => *res1 = Err(e),
-                    },
-                    Err(_) => (),
-                };
-            }
-            append_result(&mut err.suggestions, parent_err.suggestions.clone());
+                // There are two different error messages user might receive at
+                // this point:
+                // - E0412 cannot find type `{}` in this scope
+                // - E0433 failed to resolve: use of undeclared type or module `{}`
+                //
+                // The first one is emitted for paths in type-position, and the
+                // latter one - for paths in expression-position.
+                //
+                // Thus (since we're in expression-position at this point), not to
+                // confuse the user, we want to keep the *message* from E0433 (so
+                // `parent_err`), but we want *hints* from E0412 (so `err`).
+                //
+                // And that's what happens below - we're just mixing both messages
+                // into a single one.
+                let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
+
+                // overwrite all properties with the parent's error message
+                err.messages = take(&mut parent_err.messages);
+                err.code = take(&mut parent_err.code);
+                swap(&mut err.span, &mut parent_err.span);
+                err.children = take(&mut parent_err.children);
+                err.sort_span = parent_err.sort_span;
+                err.is_lint = parent_err.is_lint.clone();
+
+                // merge the parent's suggestions with the typo suggestions
+                fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
+                    match res1 {
+                        Ok(vec1) => match res2 {
+                            Ok(mut vec2) => vec1.append(&mut vec2),
+                            Err(e) => *res1 = Err(e),
+                        },
+                        Err(_) => (),
+                    };
+                }
+                append_result(&mut err.suggestions, parent_err.suggestions.clone());
 
-            parent_err.cancel();
+                parent_err.cancel();
 
-            let def_id = this.parent_scope.module.nearest_parent_mod();
+                let def_id = this.parent_scope.module.nearest_parent_mod();
 
-            if this.should_report_errs() {
-                if candidates.is_empty() {
-                    if path.len() == 2
-                        && let [segment] = prefix_path
-                    {
-                        // Delay to check whether methond name is an associated function or not
-                        // ```
-                        // let foo = Foo {};
-                        // foo::bar(); // possibly suggest to foo.bar();
-                        //```
-                        err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod);
+                if this.should_report_errs() {
+                    if candidates.is_empty() {
+                        if path.len() == 2
+                            && let [segment] = prefix_path
+                        {
+                            // Delay to check whether methond name is an associated function or not
+                            // ```
+                            // let foo = Foo {};
+                            // foo::bar(); // possibly suggest to foo.bar();
+                            //```
+                            err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod);
+                        } else {
+                            // When there is no suggested imports, we can just emit the error
+                            // and suggestions immediately. Note that we bypass the usually error
+                            // reporting routine (ie via `self.r.report_error`) because we need
+                            // to post-process the `ResolutionError` above.
+                            err.emit();
+                        }
                     } else {
-                        // When there is no suggested imports, we can just emit the error
-                        // and suggestions immediately. Note that we bypass the usually error
-                        // reporting routine (ie via `self.r.report_error`) because we need
-                        // to post-process the `ResolutionError` above.
-                        err.emit();
+                        // If there are suggested imports, the error reporting is delayed
+                        this.r.use_injections.push(UseError {
+                            err,
+                            candidates,
+                            def_id,
+                            instead: false,
+                            suggestion: None,
+                            path: prefix_path.into(),
+                            is_call: source.is_call(),
+                        });
                     }
                 } else {
-                    // If there are suggested imports, the error reporting is delayed
-                    this.r.use_injections.push(UseError {
-                        err,
-                        candidates,
-                        def_id,
-                        instead: false,
-                        suggestion: None,
-                        path: prefix_path.into(),
-                        is_call: source.is_call(),
-                    });
+                    err.cancel();
                 }
-            } else {
-                err.cancel();
-            }
 
-            // We don't return `Some(parent_err)` here, because the error will
-            // be already printed either immediately or as part of the `use` injections
-            None
-        };
+                // We don't return `Some(parent_err)` here, because the error will
+                // be already printed either immediately or as part of the `use` injections
+                None
+            };
 
         let partial_res = match self.resolve_qpath_anywhere(
             qself,
@@ -4205,7 +4206,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     /// A wrapper around [`Resolver::report_error`].
     ///
     /// This doesn't emit errors for function bodies if this is rustdoc.
-    fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) {
+    fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'ra>) {
         if self.should_report_errs() {
             self.r.report_error(span, resolution_error);
         }
@@ -4229,7 +4230,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         span: Span,
         defer_to_typeck: bool,
         finalize: Finalize,
-    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> {
+    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
         let mut fin_res = None;
 
         for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
@@ -4271,7 +4272,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         path: &[Segment],
         ns: Namespace,
         finalize: Finalize,
-    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> {
+    ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
         debug!(
             "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
             qself, path, ns, finalize,
@@ -4781,16 +4782,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 if let Some(res) = res
                     && let Some(def_id) = res.opt_def_id()
                     && !def_id.is_local()
+                    && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
+                    && matches!(
+                        self.r.tcx.sess.opts.resolve_doc_links,
+                        ResolveDocLinks::ExportedMetadata
+                    )
                 {
-                    if self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
-                        && matches!(
-                            self.r.tcx.sess.opts.resolve_doc_links,
-                            ResolveDocLinks::ExportedMetadata
-                        )
-                    {
-                        // Encoding foreign def ids in proc macro crate metadata will ICE.
-                        return None;
-                    }
+                    // Encoding foreign def ids in proc macro crate metadata will ICE.
+                    return None;
                 }
                 res
             });
@@ -4922,8 +4921,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
 /// Walks the whole crate in DFS order, visiting each item, counting the declared number of
 /// lifetime generic parameters and function parameters.
-struct ItemInfoCollector<'a, 'b, 'tcx> {
-    r: &'b mut Resolver<'a, 'tcx>,
+struct ItemInfoCollector<'a, 'ra, 'tcx> {
+    r: &'a mut Resolver<'ra, 'tcx>,
 }
 
 impl ItemInfoCollector<'_, '_, '_> {
@@ -4990,7 +4989,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
         visit::walk_crate(&mut ItemInfoCollector { r: self }, krate);
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 098509cd1d5..1c584bf8338 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -170,7 +170,7 @@ impl TypoCandidate {
     }
 }
 
-impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
+impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
     fn make_base_error(
         &mut self,
         path: &[Segment],
@@ -2255,30 +2255,29 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
     fn let_binding_suggestion(&mut self, err: &mut Diag<'_>, ident_span: Span) -> bool {
         if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) = self.diag_metadata.in_assignment
             && let ast::ExprKind::Path(None, ref path) = lhs.kind
+            && !ident_span.from_expansion()
         {
-            if !ident_span.from_expansion() {
-                let (span, text) = match path.segments.first() {
-                    Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => {
-                        // a special case for #117894
-                        let name = name.strip_prefix('_').unwrap_or(name);
-                        (ident_span, format!("let {name}"))
-                    }
-                    _ => (ident_span.shrink_to_lo(), "let ".to_string()),
-                };
+            let (span, text) = match path.segments.first() {
+                Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => {
+                    // a special case for #117894
+                    let name = name.strip_prefix('_').unwrap_or(name);
+                    (ident_span, format!("let {name}"))
+                }
+                _ => (ident_span.shrink_to_lo(), "let ".to_string()),
+            };
 
-                err.span_suggestion_verbose(
-                    span,
-                    "you might have meant to introduce a new binding",
-                    text,
-                    Applicability::MaybeIncorrect,
-                );
-                return true;
-            }
+            err.span_suggestion_verbose(
+                span,
+                "you might have meant to introduce a new binding",
+                text,
+                Applicability::MaybeIncorrect,
+            );
+            return true;
         }
         false
     }
 
-    fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
+    fn find_module(&mut self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> {
         let mut result = None;
         let mut seen_modules = FxHashSet::default();
         let root_did = self.r.graph_root.def_id();
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 8ffd00d1b2e..c05bd9e72ea 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -113,14 +113,14 @@ impl Determinacy {
 /// This enum is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
 #[derive(Clone, Copy, Debug)]
-enum Scope<'a> {
+enum Scope<'ra> {
     DeriveHelpers(LocalExpnId),
     DeriveHelpersCompat,
-    MacroRules(MacroRulesScopeRef<'a>),
+    MacroRules(MacroRulesScopeRef<'ra>),
     CrateRoot,
     // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
     // lint if it should be reported.
-    Module(Module<'a>, Option<NodeId>),
+    Module(Module<'ra>, Option<NodeId>),
     MacroUsePrelude,
     BuiltinAttrs,
     ExternPrelude,
@@ -134,7 +134,7 @@ enum Scope<'a> {
 /// This enum is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
 #[derive(Clone, Copy, Debug)]
-enum ScopeSet<'a> {
+enum ScopeSet<'ra> {
     /// All scopes with the given namespace.
     All(Namespace),
     /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
@@ -143,7 +143,7 @@ enum ScopeSet<'a> {
     Macro(MacroKind),
     /// All scopes with the given namespace, used for partially performing late resolution.
     /// The node id enables lints and is used for reporting them.
-    Late(Namespace, Module<'a>, Option<NodeId>),
+    Late(Namespace, Module<'ra>, Option<NodeId>),
 }
 
 /// Everything you need to know about a name's location to resolve it.
@@ -151,17 +151,17 @@ enum ScopeSet<'a> {
 /// This struct is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
 #[derive(Clone, Copy, Debug)]
-struct ParentScope<'a> {
-    module: Module<'a>,
+struct ParentScope<'ra> {
+    module: Module<'ra>,
     expansion: LocalExpnId,
-    macro_rules: MacroRulesScopeRef<'a>,
-    derives: &'a [ast::Path],
+    macro_rules: MacroRulesScopeRef<'ra>,
+    derives: &'ra [ast::Path],
 }
 
-impl<'a> ParentScope<'a> {
+impl<'ra> ParentScope<'ra> {
     /// Creates a parent scope with the passed argument used as the module scope component,
     /// and other scope components set to default empty values.
-    fn module(module: Module<'a>, resolver: &Resolver<'a, '_>) -> ParentScope<'a> {
+    fn module(module: Module<'ra>, resolver: &Resolver<'ra, '_>) -> ParentScope<'ra> {
         ParentScope {
             module,
             expansion: LocalExpnId::ROOT,
@@ -172,6 +172,29 @@ impl<'a> ParentScope<'a> {
 }
 
 #[derive(Copy, Debug, Clone)]
+struct InvocationParent {
+    parent_def: LocalDefId,
+    pending_anon_const_info: Option<PendingAnonConstInfo>,
+    impl_trait_context: ImplTraitContext,
+    in_attr: bool,
+}
+
+impl InvocationParent {
+    const ROOT: Self = Self {
+        parent_def: CRATE_DEF_ID,
+        pending_anon_const_info: None,
+        impl_trait_context: ImplTraitContext::Existential,
+        in_attr: false,
+    };
+}
+
+#[derive(Copy, Debug, Clone)]
+struct PendingAnonConstInfo {
+    id: NodeId,
+    span: Span,
+}
+
+#[derive(Copy, Debug, Clone)]
 enum ImplTraitContext {
     Existential,
     Universal,
@@ -203,7 +226,7 @@ struct BindingError {
 }
 
 #[derive(Debug)]
-enum ResolutionError<'a> {
+enum ResolutionError<'ra> {
     /// Error E0401: can't use type or const parameters from outer item.
     GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
     /// Error E0403: the name is already used for a type or const parameter in this generic
@@ -216,7 +239,7 @@ enum ResolutionError<'a> {
     /// Error E0438: const is not a member of trait.
     ConstNotMemberOfTrait(Ident, String, Option<Symbol>),
     /// Error E0408: variable `{}` is not bound in all patterns.
-    VariableNotBoundInPattern(BindingError, ParentScope<'a>),
+    VariableNotBoundInPattern(BindingError, ParentScope<'ra>),
     /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
     VariableBoundWithDifferentMode(Symbol, Span),
     /// Error E0415: identifier is bound more than once in this parameter list.
@@ -236,7 +259,7 @@ enum ResolutionError<'a> {
         segment: Option<Symbol>,
         label: String,
         suggestion: Option<Suggestion>,
-        module: Option<ModuleOrUniformRoot<'a>>,
+        module: Option<ModuleOrUniformRoot<'ra>>,
     },
     /// Error E0434: can't capture dynamic environment in a fn item.
     CannotCaptureDynamicEnvironmentInFnItem,
@@ -377,12 +400,12 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
 /// items are visible in their whole block, while `Res`es only from the place they are defined
 /// forward.
 #[derive(Debug, Copy, Clone)]
-enum LexicalScopeBinding<'a> {
-    Item(NameBinding<'a>),
+enum LexicalScopeBinding<'ra> {
+    Item(NameBinding<'ra>),
     Res(Res),
 }
 
-impl<'a> LexicalScopeBinding<'a> {
+impl<'ra> LexicalScopeBinding<'ra> {
     fn res(self) -> Res {
         match self {
             LexicalScopeBinding::Item(binding) => binding.res(),
@@ -392,9 +415,9 @@ impl<'a> LexicalScopeBinding<'a> {
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
-enum ModuleOrUniformRoot<'a> {
+enum ModuleOrUniformRoot<'ra> {
     /// Regular module.
-    Module(Module<'a>),
+    Module(Module<'ra>),
 
     /// Virtual module that denotes resolution in crate root with fallback to extern prelude.
     CrateRootAndExternPrelude,
@@ -410,8 +433,8 @@ enum ModuleOrUniformRoot<'a> {
 }
 
 #[derive(Debug)]
-enum PathResult<'a> {
-    Module(ModuleOrUniformRoot<'a>),
+enum PathResult<'ra> {
+    Module(ModuleOrUniformRoot<'ra>),
     NonModule(PartialRes),
     Indeterminate,
     Failed {
@@ -432,20 +455,20 @@ enum PathResult<'a> {
         /// ```
         ///
         /// In this case, `module` will point to `a`.
-        module: Option<ModuleOrUniformRoot<'a>>,
+        module: Option<ModuleOrUniformRoot<'ra>>,
         /// The segment name of target
         segment_name: Symbol,
     },
 }
 
-impl<'a> PathResult<'a> {
+impl<'ra> PathResult<'ra> {
     fn failed(
         ident: Ident,
         is_error_from_last_segment: bool,
         finalize: bool,
-        module: Option<ModuleOrUniformRoot<'a>>,
+        module: Option<ModuleOrUniformRoot<'ra>>,
         label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
-    ) -> PathResult<'a> {
+    ) -> PathResult<'ra> {
         let (label, suggestion) =
             if finalize { label_and_suggestion() } else { (String::new(), None) };
         PathResult::Failed {
@@ -518,7 +541,7 @@ impl BindingKey {
     }
 }
 
-type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
+type Resolutions<'ra> = RefCell<FxIndexMap<BindingKey, &'ra RefCell<NameResolution<'ra>>>>;
 
 /// One node in the tree of modules.
 ///
@@ -531,15 +554,15 @@ type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution
 /// * curly-braced block with statements
 ///
 /// You can use [`ModuleData::kind`] to determine the kind of module this is.
-struct ModuleData<'a> {
+struct ModuleData<'ra> {
     /// The direct parent module (it may not be a `mod`, however).
-    parent: Option<Module<'a>>,
+    parent: Option<Module<'ra>>,
     /// What kind of module this is, because this may not be a `mod`.
     kind: ModuleKind,
 
     /// Mapping between names and their (possibly in-progress) resolutions in this module.
     /// Resolutions in modules from other crates are not populated until accessed.
-    lazy_resolutions: Resolutions<'a>,
+    lazy_resolutions: Resolutions<'ra>,
     /// True if this is a module from other crate that needs to be populated on access.
     populate_on_access: Cell<bool>,
 
@@ -549,11 +572,11 @@ struct ModuleData<'a> {
     /// Whether `#[no_implicit_prelude]` is active.
     no_implicit_prelude: bool,
 
-    glob_importers: RefCell<Vec<Import<'a>>>,
-    globs: RefCell<Vec<Import<'a>>>,
+    glob_importers: RefCell<Vec<Import<'ra>>>,
+    globs: RefCell<Vec<Import<'ra>>>,
 
     /// Used to memoize the traits in this module for faster searches through all traits in scope.
-    traits: RefCell<Option<Box<[(Ident, NameBinding<'a>)]>>>,
+    traits: RefCell<Option<Box<[(Ident, NameBinding<'ra>)]>>>,
 
     /// Span of the module itself. Used for error reporting.
     span: Span,
@@ -565,11 +588,11 @@ struct ModuleData<'a> {
 /// so we can use referential equality to compare them.
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 #[rustc_pass_by_value]
-struct Module<'a>(Interned<'a, ModuleData<'a>>);
+struct Module<'ra>(Interned<'ra, ModuleData<'ra>>);
 
-impl<'a> ModuleData<'a> {
+impl<'ra> ModuleData<'ra> {
     fn new(
-        parent: Option<Module<'a>>,
+        parent: Option<Module<'ra>>,
         kind: ModuleKind,
         expansion: ExpnId,
         span: Span,
@@ -595,11 +618,11 @@ impl<'a> ModuleData<'a> {
     }
 }
 
-impl<'a> Module<'a> {
+impl<'ra> Module<'ra> {
     fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F)
     where
-        R: AsMut<Resolver<'a, 'tcx>>,
-        F: FnMut(&mut R, Ident, Namespace, NameBinding<'a>),
+        R: AsMut<Resolver<'ra, 'tcx>>,
+        F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>),
     {
         for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
             if let Some(binding) = name_resolution.borrow().binding {
@@ -611,7 +634,7 @@ impl<'a> Module<'a> {
     /// This modifies `self` in place. The traits will be stored in `self.traits`.
     fn ensure_traits<'tcx, R>(self, resolver: &mut R)
     where
-        R: AsMut<Resolver<'a, 'tcx>>,
+        R: AsMut<Resolver<'ra, 'tcx>>,
     {
         let mut traits = self.traits.borrow_mut();
         if traits.is_none() {
@@ -656,7 +679,7 @@ impl<'a> Module<'a> {
         matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _))
     }
 
-    fn nearest_item_scope(self) -> Module<'a> {
+    fn nearest_item_scope(self) -> Module<'ra> {
         match self.kind {
             ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => {
                 self.parent.expect("enum or trait module without a parent")
@@ -686,15 +709,15 @@ impl<'a> Module<'a> {
     }
 }
 
-impl<'a> std::ops::Deref for Module<'a> {
-    type Target = ModuleData<'a>;
+impl<'ra> std::ops::Deref for Module<'ra> {
+    type Target = ModuleData<'ra>;
 
     fn deref(&self) -> &Self::Target {
         &self.0
     }
 }
 
-impl<'a> fmt::Debug for Module<'a> {
+impl<'ra> fmt::Debug for Module<'ra> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{:?}", self.res())
     }
@@ -702,9 +725,9 @@ impl<'a> fmt::Debug for Module<'a> {
 
 /// Records a possibly-private value, type, or module definition.
 #[derive(Clone, Copy, Debug)]
-struct NameBindingData<'a> {
-    kind: NameBindingKind<'a>,
-    ambiguity: Option<(NameBinding<'a>, AmbiguityKind)>,
+struct NameBindingData<'ra> {
+    kind: NameBindingKind<'ra>,
+    ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>,
     /// Produce a warning instead of an error when reporting ambiguities inside this binding.
     /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required.
     warn_ambiguity: bool,
@@ -715,26 +738,26 @@ struct NameBindingData<'a> {
 
 /// All name bindings are unique and allocated on a same arena,
 /// so we can use referential equality to compare them.
-type NameBinding<'a> = Interned<'a, NameBindingData<'a>>;
+type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>;
 
-trait ToNameBinding<'a> {
-    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a>;
+trait ToNameBinding<'ra> {
+    fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra>;
 }
 
-impl<'a> ToNameBinding<'a> for NameBinding<'a> {
-    fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> NameBinding<'a> {
+impl<'ra> ToNameBinding<'ra> for NameBinding<'ra> {
+    fn to_name_binding(self, _: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
         self
     }
 }
 
 #[derive(Clone, Copy, Debug)]
-enum NameBindingKind<'a> {
+enum NameBindingKind<'ra> {
     Res(Res),
-    Module(Module<'a>),
-    Import { binding: NameBinding<'a>, import: Import<'a> },
+    Module(Module<'ra>),
+    Import { binding: NameBinding<'ra>, import: Import<'ra> },
 }
 
-impl<'a> NameBindingKind<'a> {
+impl<'ra> NameBindingKind<'ra> {
     /// Is this a name binding of an import?
     fn is_import(&self) -> bool {
         matches!(*self, NameBindingKind::Import { .. })
@@ -742,12 +765,12 @@ impl<'a> NameBindingKind<'a> {
 }
 
 #[derive(Debug)]
-struct PrivacyError<'a> {
+struct PrivacyError<'ra> {
     ident: Ident,
-    binding: NameBinding<'a>,
+    binding: NameBinding<'ra>,
     dedup_span: Span,
     outermost_res: Option<(Res, Ident)>,
-    parent_scope: ParentScope<'a>,
+    parent_scope: ParentScope<'ra>,
     /// Is the format `use a::{b,c}`?
     single_nested: bool,
 }
@@ -812,18 +835,18 @@ enum AmbiguityErrorMisc {
     None,
 }
 
-struct AmbiguityError<'a> {
+struct AmbiguityError<'ra> {
     kind: AmbiguityKind,
     ident: Ident,
-    b1: NameBinding<'a>,
-    b2: NameBinding<'a>,
+    b1: NameBinding<'ra>,
+    b2: NameBinding<'ra>,
     misc1: AmbiguityErrorMisc,
     misc2: AmbiguityErrorMisc,
     warning: bool,
 }
 
-impl<'a> NameBindingData<'a> {
-    fn module(&self) -> Option<Module<'a>> {
+impl<'ra> NameBindingData<'ra> {
+    fn module(&self) -> Option<Module<'ra>> {
         match self.kind {
             NameBindingKind::Module(module) => Some(module),
             NameBindingKind::Import { binding, .. } => binding.module(),
@@ -947,8 +970,8 @@ impl<'a> NameBindingData<'a> {
 }
 
 #[derive(Default, Clone)]
-struct ExternPreludeEntry<'a> {
-    binding: Option<NameBinding<'a>>,
+struct ExternPreludeEntry<'ra> {
+    binding: Option<NameBinding<'ra>>,
     introduced_by_item: bool,
 }
 
@@ -985,16 +1008,16 @@ impl MacroData {
 /// The main resolver class.
 ///
 /// This is the visitor that walks the whole crate.
-pub struct Resolver<'a, 'tcx> {
+pub struct Resolver<'ra, 'tcx> {
     tcx: TyCtxt<'tcx>,
 
     /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
     expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
 
-    graph_root: Module<'a>,
+    graph_root: Module<'ra>,
 
-    prelude: Option<Module<'a>>,
-    extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
+    prelude: Option<Module<'ra>>,
+    extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'ra>>,
 
     /// N.B., this is used only for better diagnostics, not name resolution itself.
     field_names: LocalDefIdMap<Vec<Ident>>,
@@ -1004,10 +1027,10 @@ pub struct Resolver<'a, 'tcx> {
     field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
 
     /// All imports known to succeed or fail.
-    determined_imports: Vec<Import<'a>>,
+    determined_imports: Vec<Import<'ra>>,
 
     /// All non-determined imports.
-    indeterminate_imports: Vec<Import<'a>>,
+    indeterminate_imports: Vec<Import<'ra>>,
 
     // Spans for local variables found during pattern resolution.
     // Used for suggestions during error reporting.
@@ -1018,7 +1041,7 @@ pub struct Resolver<'a, 'tcx> {
     /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
     import_res_map: NodeMap<PerNS<Option<Res>>>,
     /// An import will be inserted into this map if it has been used.
-    import_use_map: FxHashMap<Import<'a>, Used>,
+    import_use_map: FxHashMap<Import<'ra>, Used>,
     /// Resolutions for labels (node IDs of their corresponding blocks or loops).
     label_res_map: NodeMap<NodeId>,
     /// Resolutions for lifetimes.
@@ -1045,13 +1068,13 @@ pub struct Resolver<'a, 'tcx> {
     ///
     /// There will be an anonymous module created around `g` with the ID of the
     /// entry block for `f`.
-    block_map: NodeMap<Module<'a>>,
+    block_map: NodeMap<Module<'ra>>,
     /// A fake module that contains no definition and no prelude. Used so that
     /// some AST passes can generate identifiers that only resolve to local or
     /// lang items.
-    empty_module: Module<'a>,
-    module_map: FxHashMap<DefId, Module<'a>>,
-    binding_parent_modules: FxHashMap<NameBinding<'a>, Module<'a>>,
+    empty_module: Module<'ra>,
+    module_map: FxHashMap<DefId, Module<'ra>>,
+    binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
 
     underscore_disambiguator: u32,
     /// Disambiguator for anonymous adts.
@@ -1065,57 +1088,57 @@ pub struct Resolver<'a, 'tcx> {
     maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
 
     /// Privacy errors are delayed until the end in order to deduplicate them.
-    privacy_errors: Vec<PrivacyError<'a>>,
+    privacy_errors: Vec<PrivacyError<'ra>>,
     /// Ambiguity errors are delayed for deduplication.
-    ambiguity_errors: Vec<AmbiguityError<'a>>,
+    ambiguity_errors: Vec<AmbiguityError<'ra>>,
     /// `use` injections are delayed for better placement and deduplication.
     use_injections: Vec<UseError<'tcx>>,
     /// Crate-local macro expanded `macro_export` referred to by a module-relative path.
     macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
 
-    arenas: &'a ResolverArenas<'a>,
-    dummy_binding: NameBinding<'a>,
-    builtin_types_bindings: FxHashMap<Symbol, NameBinding<'a>>,
-    builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'a>>,
-    registered_tool_bindings: FxHashMap<Ident, NameBinding<'a>>,
+    arenas: &'ra ResolverArenas<'ra>,
+    dummy_binding: NameBinding<'ra>,
+    builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
+    builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
+    registered_tool_bindings: FxHashMap<Ident, NameBinding<'ra>>,
     /// Binding for implicitly declared names that come with a module,
     /// like `self` (not yet used), or `crate`/`$crate` (for root modules).
-    module_self_bindings: FxHashMap<Module<'a>, NameBinding<'a>>,
+    module_self_bindings: FxHashMap<Module<'ra>, NameBinding<'ra>>,
 
     used_extern_options: FxHashSet<Symbol>,
     macro_names: FxHashSet<Ident>,
     builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
     registered_tools: &'tcx RegisteredTools,
-    macro_use_prelude: FxHashMap<Symbol, NameBinding<'a>>,
+    macro_use_prelude: FxHashMap<Symbol, NameBinding<'ra>>,
     macro_map: FxHashMap<DefId, MacroData>,
     dummy_ext_bang: Lrc<SyntaxExtension>,
     dummy_ext_derive: Lrc<SyntaxExtension>,
     non_macro_attr: MacroData,
-    local_macro_def_scopes: FxHashMap<LocalDefId, Module<'a>>,
-    ast_transform_scopes: FxHashMap<LocalExpnId, Module<'a>>,
+    local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>,
+    ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
     unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
     unused_macro_rules: FxHashMap<(LocalDefId, usize), (Ident, Span)>,
     proc_macro_stubs: FxHashSet<LocalDefId>,
     /// Traces collected during macro resolution and validated when it's complete.
     single_segment_macro_resolutions:
-        Vec<(Ident, MacroKind, ParentScope<'a>, Option<NameBinding<'a>>)>,
+        Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>)>,
     multi_segment_macro_resolutions:
-        Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>, Option<Res>, Namespace)>,
-    builtin_attrs: Vec<(Ident, ParentScope<'a>)>,
+        Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>,
+    builtin_attrs: Vec<(Ident, ParentScope<'ra>)>,
     /// `derive(Copy)` marks items they are applied to so they are treated specially later.
     /// Derive macros cannot modify the item themselves and have to store the markers in the global
     /// context, so they attach the markers to derive container IDs using this resolver table.
     containers_deriving_copy: FxHashSet<LocalExpnId>,
     /// Parent scopes in which the macros were invoked.
     /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
-    invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'a>>,
+    invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'ra>>,
     /// `macro_rules` scopes *produced* by expanding the macro invocations,
     /// include all the `macro_rules` items and other invocations generated by them.
-    output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'a>>,
+    output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'ra>>,
     /// `macro_rules` scopes produced by `macro_rules` item definitions.
-    macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>,
+    macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'ra>>,
     /// Helper attributes that are in scope for the given expansion.
-    helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'a>)>>,
+    helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'ra>)>>,
     /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
     /// with the given `ExpnId`.
     derive_data: FxHashMap<LocalExpnId, DeriveData>,
@@ -1123,9 +1146,9 @@ pub struct Resolver<'a, 'tcx> {
     /// Avoid duplicated errors for "name already defined".
     name_already_seen: FxHashMap<Symbol, Span>,
 
-    potentially_unused_imports: Vec<Import<'a>>,
+    potentially_unused_imports: Vec<Import<'ra>>,
 
-    potentially_unnecessary_qualifications: Vec<UnnecessaryQualification<'a>>,
+    potentially_unnecessary_qualifications: Vec<UnnecessaryQualification<'ra>>,
 
     /// Table for mapping struct IDs into struct constructor IDs,
     /// it's not used during normal resolution, only for better error reporting.
@@ -1144,7 +1167,7 @@ pub struct Resolver<'a, 'tcx> {
     /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
     /// we know what parent node that fragment should be attached to thanks to this table,
     /// and how the `impl Trait` fragments were introduced.
-    invocation_parents: FxHashMap<LocalExpnId, (LocalDefId, ImplTraitContext, bool /*in_attr*/)>,
+    invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
 
     /// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
     /// FIXME: Replace with a more general AST map (together with some other fields).
@@ -1186,28 +1209,29 @@ pub struct Resolver<'a, 'tcx> {
     current_crate_outer_attr_insert_span: Span,
 }
 
-/// Nothing really interesting here; it just provides memory for the rest of the crate.
+/// This provides memory for the rest of the crate. The `'ra` lifetime that is
+/// used by many types in this crate is an abbreviation of `ResolverArenas`.
 #[derive(Default)]
-pub struct ResolverArenas<'a> {
-    modules: TypedArena<ModuleData<'a>>,
-    local_modules: RefCell<Vec<Module<'a>>>,
-    imports: TypedArena<ImportData<'a>>,
-    name_resolutions: TypedArena<RefCell<NameResolution<'a>>>,
+pub struct ResolverArenas<'ra> {
+    modules: TypedArena<ModuleData<'ra>>,
+    local_modules: RefCell<Vec<Module<'ra>>>,
+    imports: TypedArena<ImportData<'ra>>,
+    name_resolutions: TypedArena<RefCell<NameResolution<'ra>>>,
     ast_paths: TypedArena<ast::Path>,
     dropless: DroplessArena,
 }
 
-impl<'a> ResolverArenas<'a> {
+impl<'ra> ResolverArenas<'ra> {
     fn new_module(
-        &'a self,
-        parent: Option<Module<'a>>,
+        &'ra self,
+        parent: Option<Module<'ra>>,
         kind: ModuleKind,
         expn_id: ExpnId,
         span: Span,
         no_implicit_prelude: bool,
-        module_map: &mut FxHashMap<DefId, Module<'a>>,
-        module_self_bindings: &mut FxHashMap<Module<'a>, NameBinding<'a>>,
-    ) -> Module<'a> {
+        module_map: &mut FxHashMap<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(
             parent,
             kind,
@@ -1227,37 +1251,37 @@ impl<'a> ResolverArenas<'a> {
         }
         module
     }
-    fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> {
+    fn local_modules(&'ra self) -> std::cell::Ref<'ra, Vec<Module<'ra>>> {
         self.local_modules.borrow()
     }
-    fn alloc_name_binding(&'a self, name_binding: NameBindingData<'a>) -> NameBinding<'a> {
+    fn alloc_name_binding(&'ra self, name_binding: NameBindingData<'ra>) -> NameBinding<'ra> {
         Interned::new_unchecked(self.dropless.alloc(name_binding))
     }
-    fn alloc_import(&'a self, import: ImportData<'a>) -> Import<'a> {
+    fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
         Interned::new_unchecked(self.imports.alloc(import))
     }
-    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
+    fn alloc_name_resolution(&'ra self) -> &'ra RefCell<NameResolution<'ra>> {
         self.name_resolutions.alloc(Default::default())
     }
-    fn alloc_macro_rules_scope(&'a self, scope: MacroRulesScope<'a>) -> MacroRulesScopeRef<'a> {
+    fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
         Interned::new_unchecked(self.dropless.alloc(Cell::new(scope)))
     }
     fn alloc_macro_rules_binding(
-        &'a self,
-        binding: MacroRulesBinding<'a>,
-    ) -> &'a MacroRulesBinding<'a> {
+        &'ra self,
+        binding: MacroRulesBinding<'ra>,
+    ) -> &'ra MacroRulesBinding<'ra> {
         self.dropless.alloc(binding)
     }
-    fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] {
+    fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
         self.ast_paths.alloc_from_iter(paths.iter().cloned())
     }
-    fn alloc_pattern_spans(&'a self, spans: impl Iterator<Item = Span>) -> &'a [Span] {
+    fn alloc_pattern_spans(&'ra self, spans: impl Iterator<Item = Span>) -> &'ra [Span] {
         self.dropless.alloc_from_iter(spans)
     }
 }
 
-impl<'a, 'tcx> AsMut<Resolver<'a, 'tcx>> for Resolver<'a, 'tcx> {
-    fn as_mut(&mut self) -> &mut Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> {
+    fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
         self
     }
 }
@@ -1341,14 +1365,14 @@ impl<'tcx> Resolver<'_, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     pub fn new(
         tcx: TyCtxt<'tcx>,
         attrs: &[ast::Attribute],
         crate_span: Span,
         current_crate_outer_attr_insert_span: Span,
-        arenas: &'a ResolverArenas<'a>,
-    ) -> Resolver<'a, '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_self_bindings = FxHashMap::default();
@@ -1381,8 +1405,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
 
         let mut invocation_parents = FxHashMap::default();
-        invocation_parents
-            .insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential, false));
+        invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
 
         let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = tcx
             .sess
@@ -1541,12 +1564,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn new_module(
         &mut self,
-        parent: Option<Module<'a>>,
+        parent: Option<Module<'ra>>,
         kind: ModuleKind,
         expn_id: ExpnId,
         span: Span,
         no_implicit_prelude: bool,
-    ) -> Module<'a> {
+    ) -> Module<'ra> {
         let module_map = &mut self.module_map;
         let module_self_bindings = &mut self.module_self_bindings;
         self.arenas.new_module(
@@ -1578,7 +1601,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self.lint_buffer
     }
 
-    pub fn arenas() -> ResolverArenas<'a> {
+    pub fn arenas() -> ResolverArenas<'ra> {
         Default::default()
     }
 
@@ -1719,8 +1742,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn traits_in_scope(
         &mut self,
-        current_trait: Option<Module<'a>>,
-        parent_scope: &ParentScope<'a>,
+        current_trait: Option<Module<'ra>>,
+        parent_scope: &ParentScope<'ra>,
         ctxt: SyntaxContext,
         assoc_item: Option<(Symbol, Namespace)>,
     ) -> Vec<TraitCandidate> {
@@ -1754,7 +1777,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn traits_in_module(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         assoc_item: Option<(Symbol, Namespace)>,
         found_traits: &mut Vec<TraitCandidate>,
     ) {
@@ -1776,7 +1799,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     // associated items.
     fn trait_may_have_item(
         &mut self,
-        trait_module: Option<Module<'a>>,
+        trait_module: Option<Module<'ra>>,
         assoc_item: Option<(Symbol, Namespace)>,
     ) -> bool {
         match (trait_module, assoc_item) {
@@ -1822,7 +1845,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         BindingKey { ident, ns, disambiguator }
     }
 
-    fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
+    fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
         if module.populate_on_access.get() {
             module.populate_on_access.set(false);
             self.build_reduced_graph_external(module);
@@ -1832,9 +1855,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn resolution(
         &mut self,
-        module: Module<'a>,
+        module: Module<'ra>,
         key: BindingKey,
-    ) -> &'a RefCell<NameResolution<'a>> {
+    ) -> &'ra RefCell<NameResolution<'ra>> {
         *self
             .resolutions(module)
             .borrow_mut()
@@ -1860,14 +1883,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         false
     }
 
-    fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'a>, used: Used) {
+    fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) {
         self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity);
     }
 
     fn record_use_inner(
         &mut self,
         ident: Ident,
-        used_binding: NameBinding<'a>,
+        used_binding: NameBinding<'ra>,
         used: Used,
         warn_ambiguity: bool,
     ) {
@@ -1929,7 +1952,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
+    fn resolve_crate_root(&mut self, ident: Ident) -> Module<'ra> {
         debug!("resolve_crate_root({:?})", ident);
         let mut ctxt = ident.span.ctxt();
         let mark = if ident.name == kw::DollarCrate {
@@ -2002,7 +2025,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         module
     }
 
-    fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
+    fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'ra>) -> Module<'ra> {
         let mut module = self.expect_module(module.nearest_parent_mod());
         while module.span.ctxt().normalize_to_macros_2_0() != *ctxt {
             let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark()));
@@ -2026,12 +2049,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn is_accessible_from(
         &self,
         vis: ty::Visibility<impl Into<DefId>>,
-        module: Module<'a>,
+        module: Module<'ra>,
     ) -> bool {
         vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
     }
 
-    fn set_binding_parent_module(&mut self, binding: NameBinding<'a>, module: Module<'a>) {
+    fn set_binding_parent_module(&mut self, binding: NameBinding<'ra>, module: Module<'ra>) {
         if let Some(old_module) = self.binding_parent_modules.insert(binding, module) {
             if module != old_module {
                 span_bug!(binding.span, "parent module is reset for binding");
@@ -2041,8 +2064,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn disambiguate_macro_rules_vs_modularized(
         &self,
-        macro_rules: NameBinding<'a>,
-        modularized: NameBinding<'a>,
+        macro_rules: NameBinding<'ra>,
+        modularized: NameBinding<'ra>,
     ) -> bool {
         // Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules"
         // is disambiguated to mitigate regressions from macro modularization.
@@ -2059,7 +2082,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'a>> {
+    fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
         if ident.is_path_segment_keyword() {
             // Make sure `self`, `super` etc produce an error when passed to here.
             return None;
@@ -2108,7 +2131,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path_str: &str,
         ns: Namespace,
-        parent_scope: ParentScope<'a>,
+        parent_scope: ParentScope<'ra>,
     ) -> Option<Res> {
         let mut segments =
             Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident));
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 7203fbe4a0c..b4f277c4244 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -42,9 +42,9 @@ use crate::errors::{
 use crate::imports::Import;
 use crate::Namespace::*;
 use crate::{
-    BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, MacroData, ModuleKind,
-    ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError,
-    Resolver, ScopeSet, Segment, ToNameBinding, Used,
+    BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
+    ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
+    ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used,
 };
 
 type Res = def::Res<NodeId>;
@@ -52,10 +52,10 @@ type Res = def::Res<NodeId>;
 /// Binding produced by a `macro_rules` item.
 /// Not modularized, can shadow previous `macro_rules` bindings, etc.
 #[derive(Debug)]
-pub(crate) struct MacroRulesBinding<'a> {
-    pub(crate) binding: NameBinding<'a>,
+pub(crate) struct MacroRulesBinding<'ra> {
+    pub(crate) binding: NameBinding<'ra>,
     /// `macro_rules` scope into which the `macro_rules` item was planted.
-    pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'a>,
+    pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>,
     pub(crate) ident: Ident,
 }
 
@@ -65,11 +65,11 @@ pub(crate) struct MacroRulesBinding<'a> {
 /// Some macro invocations need to introduce `macro_rules` scopes too because they
 /// can potentially expand into macro definitions.
 #[derive(Copy, Clone, Debug)]
-pub(crate) enum MacroRulesScope<'a> {
+pub(crate) enum MacroRulesScope<'ra> {
     /// Empty "root" scope at the crate start containing no names.
     Empty,
     /// The scope introduced by a `macro_rules!` macro definition.
-    Binding(&'a MacroRulesBinding<'a>),
+    Binding(&'ra MacroRulesBinding<'ra>),
     /// The scope introduced by a macro invocation that can potentially
     /// create a `macro_rules!` macro definition.
     Invocation(LocalExpnId),
@@ -81,7 +81,7 @@ pub(crate) enum MacroRulesScope<'a> {
 /// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
 /// which usually grow linearly with the number of macro invocations
 /// in a module (including derives) and hurt performance.
-pub(crate) type MacroRulesScopeRef<'a> = Interned<'a, Cell<MacroRulesScope<'a>>>;
+pub(crate) type MacroRulesScopeRef<'ra> = Interned<'ra, Cell<MacroRulesScope<'ra>>>;
 
 /// Macro namespace is separated into two sub-namespaces, one for bang macros and
 /// one for attribute-like macros (attributes, derives).
@@ -177,13 +177,13 @@ fn soft_custom_inner_attributes_gate(path: &ast::Path, invoc: &Invocation) -> bo
     false
 }
 
-impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
     fn next_node_id(&mut self) -> NodeId {
         self.next_node_id()
     }
 
     fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId {
-        self.invocation_parents[&id].0
+        self.invocation_parents[&id].parent_def
     }
 
     fn resolve_dollar_crates(&mut self) {
@@ -303,12 +303,12 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
             .invocation_parents
             .get(&invoc_id)
             .or_else(|| self.invocation_parents.get(&eager_expansion_root))
-            .filter(|&&(mod_def_id, _, in_attr)| {
+            .filter(|&&InvocationParent { parent_def: mod_def_id, in_attr, .. }| {
                 in_attr
                     && invoc.fragment_kind == AstFragmentKind::Expr
                     && self.tcx.def_kind(mod_def_id) == DefKind::Mod
             })
-            .map(|&(mod_def_id, ..)| mod_def_id);
+            .map(|&InvocationParent { parent_def: mod_def_id, .. }| mod_def_id);
         let (ext, res) = self.smart_resolve_macro_path(
             path,
             kind,
@@ -528,7 +528,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Resolver<'a, 'tcx> {
+impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
     /// Resolve macro path with error reporting and recovery.
     /// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
     /// for better error recovery.
@@ -538,7 +538,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         kind: MacroKind,
         supports_macro_expansion: SupportsMacroExpansion,
         inner_attr: bool,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         node_id: NodeId,
         force: bool,
         soft_custom_inner_attributes_gate: bool,
@@ -704,10 +704,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         path: &ast::Path,
         kind: Option<MacroKind>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         trace: bool,
         force: bool,
-        ignore_import: Option<Import<'a>>,
+        ignore_import: Option<Import<'ra>>,
     ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
         self.resolve_macro_or_delegation_path(
             path,
@@ -725,12 +725,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         &mut self,
         ast_path: &ast::Path,
         kind: Option<MacroKind>,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         trace: bool,
         force: bool,
         deleg_impl: Option<LocalDefId>,
         invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
-        ignore_import: Option<Import<'a>>,
+        ignore_import: Option<Import<'ra>>,
     ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
         let path_span = ast_path.span;
         let mut path = Segment::from_path(ast_path);
@@ -951,7 +951,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         let node_id = self
                             .invocation_parents
                             .get(&parent_scope.expansion)
-                            .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[id.0]);
+                            .map_or(ast::CRATE_NODE_ID, |parent| {
+                                self.def_id_to_node_id[parent.parent_def]
+                            });
                         self.lint_buffer.buffer_lint(
                             LEGACY_DERIVE_HELPERS,
                             node_id,
@@ -1045,7 +1047,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn prohibit_imported_non_macro_attrs(
         &self,
-        binding: Option<NameBinding<'a>>,
+        binding: Option<NameBinding<'ra>>,
         res: Option<Res>,
         span: Span,
     ) {
@@ -1065,9 +1067,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn report_out_of_scope_macro_calls(
         &mut self,
         path: &ast::Path,
-        parent_scope: &ParentScope<'a>,
+        parent_scope: &ParentScope<'ra>,
         invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
-        binding: Option<NameBinding<'a>>,
+        binding: Option<NameBinding<'ra>>,
     ) {
         if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
             && let Some(binding) = binding
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 976c4acb212..bed3baa30fb 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -270,12 +270,10 @@ fn strip_generics_from_path_segment(segment: Vec<char>) -> Result<String, Malfor
                 // Give a helpful error message instead of completely ignoring the angle brackets.
                 return Err(MalformedGenerics::HasFullyQualifiedSyntax);
             }
+        } else if param_depth == 0 {
+            stripped_segment.push(c);
         } else {
-            if param_depth == 0 {
-                stripped_segment.push(c);
-            } else {
-                latest_generics_chunk.push(c);
-            }
+            latest_generics_chunk.push(c);
         }
     }
 
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index 45057a3530c..a0a0dd058ff 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -207,14 +207,12 @@ fn encode_fnsig<'tcx>(
         if fn_sig.c_variadic {
             s.push('z');
         }
+    } else if fn_sig.c_variadic {
+        s.push('z');
     } else {
-        if fn_sig.c_variadic {
-            s.push('z');
-        } else {
-            // Empty parameter lists, whether declared as () or conventionally as (void), are
-            // encoded with a void parameter specifier "v".
-            s.push('v')
-        }
+        // Empty parameter lists, whether declared as () or conventionally as (void), are
+        // encoded with a void parameter specifier "v".
+        s.push('v')
     }
 
     // Close the "F..E" pair
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 01c371ee498..a4fbab8477b 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -113,6 +113,8 @@ session_split_lto_unit_requires_lto = `-Zsplit-lto-unit` requires `-Clto`, `-Clt
 
 session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`
 
+session_target_small_data_threshold_not_supported = `-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored
+
 session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored
 
 session_unleashed_feature_help_named = skipping check for `{$gate}` feature
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f3e3b36111c..908d50a041e 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -842,11 +842,6 @@ pub struct NextSolverConfig {
     /// This is only `true` if `coherence` is also enabled.
     pub globally: bool,
 }
-impl Default for NextSolverConfig {
-    fn default() -> Self {
-        NextSolverConfig { coherence: true, globally: false }
-    }
-}
 
 #[derive(Clone)]
 pub enum Input {
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 15bbd4ff7bf..462e2a97c33 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -183,6 +183,12 @@ pub(crate) struct StackProtectorNotSupportedForTarget<'a> {
 }
 
 #[derive(Diagnostic)]
+#[diag(session_target_small_data_threshold_not_supported)]
+pub(crate) struct SmallDataThresholdNotSupportedForTarget<'a> {
+    pub(crate) target_triple: &'a TargetTriple,
+}
+
+#[derive(Diagnostic)]
 #[diag(session_branch_protection_requires_aarch64)]
 pub(crate) struct BranchProtectionRequiresAArch64;
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 982a3d5cf11..e487a2501e3 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -403,7 +403,7 @@ mod desc {
     pub(crate) const parse_unpretty: &str = "`string` or `string=string`";
     pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
     pub(crate) const parse_next_solver_config: &str =
-        "either `globally` (when used without an argument), `coherence` (default) or `no`";
+        "a comma separated list of solver configurations: `globally` (default), and `coherence`";
     pub(crate) const parse_lto: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
     pub(crate) const parse_linker_plugin_lto: &str =
@@ -1105,16 +1105,27 @@ mod parse {
         }
     }
 
-    pub(crate) fn parse_next_solver_config(slot: &mut NextSolverConfig, v: Option<&str>) -> bool {
+    pub(crate) fn parse_next_solver_config(
+        slot: &mut Option<NextSolverConfig>,
+        v: Option<&str>,
+    ) -> bool {
         if let Some(config) = v {
-            *slot = match config {
-                "no" => NextSolverConfig { coherence: false, globally: false },
-                "coherence" => NextSolverConfig { coherence: true, globally: false },
-                "globally" => NextSolverConfig { coherence: true, globally: true },
-                _ => return false,
-            };
+            let mut coherence = false;
+            let mut globally = true;
+            for c in config.split(',') {
+                match c {
+                    "globally" => globally = true,
+                    "coherence" => {
+                        globally = false;
+                        coherence = true;
+                    }
+                    _ => return false,
+                }
+            }
+
+            *slot = Some(NextSolverConfig { coherence: coherence || globally, globally });
         } else {
-            *slot = NextSolverConfig { coherence: true, globally: true };
+            *slot = Some(NextSolverConfig { coherence: true, globally: true });
         }
 
         true
@@ -1867,7 +1878,7 @@ options! {
         "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: bool = (true, parse_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: yes)"),
-    next_solver: NextSolverConfig = (NextSolverConfig::default(), parse_next_solver_config, [TRACKED],
+    next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED],
         "enable and configure the next generation trait solver used by rustc"),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
         "dump facts from NLL analysis into side files (default: no)"),
@@ -2014,6 +2025,8 @@ written to standard error output)"),
     simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
         to rust's source base directory. only meant for testing purposes"),
+    small_data_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
+        "Set the threshold for objects to be stored in a \"small data\" section"),
     span_debug: bool = (false, parse_bool, [UNTRACKED],
         "forward proc_macro::Span's `Debug` impl to `Span`"),
     /// o/w tests have closure@path
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index d6c58e9d1be..1db31f5b0a7 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -340,4 +340,8 @@ impl ParseSess {
     pub fn dcx(&self) -> DiagCtxtHandle<'_> {
         self.dcx.handle()
     }
+
+    pub fn set_dcx(&mut self, dcx: DiagCtxt) {
+        self.dcx = dcx;
+    }
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 70430d82ab5..387ae1b78c4 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -30,8 +30,8 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
 use rustc_span::{FileNameDisplayPreference, RealFileName, Span, Symbol};
 use rustc_target::asm::InlineAsmArch;
 use rustc_target::spec::{
-    CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo,
-    StackProtector, Target, TargetTriple, TlsModel,
+    CodeModel, DebuginfoKind, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
+    SmallDataThresholdSupport, SplitDebuginfo, StackProtector, Target, TargetTriple, TlsModel,
 };
 
 use crate::code_stats::CodeStats;
@@ -1278,6 +1278,14 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         }
     }
 
+    if sess.opts.unstable_opts.small_data_threshold.is_some() {
+        if sess.target.small_data_threshold_support() == SmallDataThresholdSupport::None {
+            sess.dcx().emit_warn(errors::SmallDataThresholdNotSupportedForTarget {
+                target_triple: &sess.opts.target_triple,
+            })
+        }
+    }
+
     if sess.opts.unstable_opts.branch_protection.is_some() && sess.target.arch != "aarch64" {
         sess.dcx().emit_err(errors::BranchProtectionRequiresAArch64);
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 28d18f2dfcc..cbe2bafef21 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -599,7 +599,6 @@ symbols! {
         conservative_impl_trait,
         console,
         const_allocate,
-        const_arg_path,
         const_async_blocks,
         const_closures,
         const_compare_raw_pointers,
@@ -1017,6 +1016,7 @@ symbols! {
         ident,
         if_let,
         if_let_guard,
+        if_let_rescope,
         if_while_or_patterns,
         ignore,
         impl_header_lifetime_elision,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 75f4499352b..ba35a37c32c 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -381,7 +381,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                     let consts = [
                         start.unwrap_or(self.tcx.consts.unit),
                         end.unwrap_or(self.tcx.consts.unit),
-                        ty::Const::from_bool(self.tcx, include_end).into(),
+                        ty::Const::from_bool(self.tcx, include_end),
                     ];
                     // HACK: Represent as tuple until we have something better.
                     // HACK: constants are used in arrays, even if the types don't match.
diff --git a/compiler/rustc_target/src/abi/call/xtensa.rs b/compiler/rustc_target/src/abi/call/xtensa.rs
index cb61bf2c56b..d7b5fe9d4cc 100644
--- a/compiler/rustc_target/src/abi/call/xtensa.rs
+++ b/compiler/rustc_target/src/abi/call/xtensa.rs
@@ -69,29 +69,27 @@ where
 
     if must_use_stack {
         arg.make_indirect_byval(None);
-    } else {
-        if is_xtensa_aggregate(arg) {
-            // Aggregates which are <= max_size will be passed in
-            // registers if possible, so coerce to integers.
+    } else if is_xtensa_aggregate(arg) {
+        // Aggregates which are <= max_size will be passed in
+        // registers if possible, so coerce to integers.
 
-            // Use a single `xlen` int if possible, 2 * `xlen` if 2 * `xlen` alignment
-            // is required, and a 2-element `xlen` array if only `xlen` alignment is
-            // required.
-            if size <= 32 {
-                arg.cast_to(Reg::i32());
-            } else {
-                let reg = if needed_align == 2 * 32 { Reg::i64() } else { Reg::i32() };
-                let total = Size::from_bits(((size + 32 - 1) / 32) * 32);
-                arg.cast_to(Uniform::new(reg, total));
-            }
+        // Use a single `xlen` int if possible, 2 * `xlen` if 2 * `xlen` alignment
+        // is required, and a 2-element `xlen` array if only `xlen` alignment is
+        // required.
+        if size <= 32 {
+            arg.cast_to(Reg::i32());
         } else {
-            // All integral types are promoted to `xlen`
-            // width.
-            //
-            // We let the LLVM backend handle integral types >= xlen.
-            if size < 32 {
-                arg.extend_integer_width_to(32);
-            }
+            let reg = if needed_align == 2 * 32 { Reg::i64() } else { Reg::i32() };
+            let total = Size::from_bits(((size + 32 - 1) / 32) * 32);
+            arg.cast_to(Uniform::new(reg, total));
+        }
+    } else {
+        // All integral types are promoted to `xlen`
+        // width.
+        //
+        // We let the LLVM backend handle integral types >= xlen.
+        if size < 32 {
+            arg.extend_integer_width_to(32);
         }
     }
 }
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index b1fe49f76ca..e78e3222115 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -168,7 +168,26 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
         ["-platform_version".into(), platform_name, min_version, sdk_version].into_iter(),
     );
 
-    if abi != TargetAbi::MacCatalyst {
+    // We need to communicate four things to the C compiler to be able to link:
+    // - The architecture.
+    // - The operating system (and that it's an Apple platform).
+    // - The deployment target.
+    // - The environment / ABI.
+    //
+    // We'd like to use `-target` everywhere, since that can uniquely
+    // communicate all of these, but that doesn't work on GCC, and since we
+    // don't know whether the `cc` compiler is Clang, GCC, or something else,
+    // we fall back to other options that also work on GCC when compiling for
+    // macOS.
+    //
+    // Targets other than macOS are ill-supported by GCC (it doesn't even
+    // support e.g. `-miphoneos-version-min`), so in those cases we can fairly
+    // safely use `-target`. See also the following, where it is made explicit
+    // that the recommendation by LLVM developers is to use `-target`:
+    // <https://github.com/llvm/llvm-project/issues/88271>
+    if os == "macos" {
+        // `-arch` communicates the architecture.
+        //
         // CC forwards the `-arch` to the linker, so we use the same value
         // here intentionally.
         add_link_args(
@@ -176,6 +195,15 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
             LinkerFlavor::Darwin(Cc::Yes, Lld::No),
             &["-arch", arch.ld_arch()],
         );
+        // The presence of `-mmacosx-version-min` makes CC default to macOS,
+        // and it sets the deployment target.
+        let (major, minor, patch) = deployment_target(os, arch, abi);
+        let opt = format!("-mmacosx-version-min={major}.{minor}.{patch}").into();
+        add_link_args_iter(&mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), [opt].into_iter());
+        // macOS has no environment, so with these two, we've told CC all the
+        // desired parameters.
+        //
+        // We avoid `-m32`/`-m64`, as this is already encoded by `-arch`.
     } else {
         add_link_args_iter(
             &mut args,
@@ -323,12 +351,18 @@ fn deployment_target(os: &str, arch: Arch, abi: TargetAbi) -> (u16, u8, u8) {
     };
 
     // On certain targets it makes sense to raise the minimum OS version.
+    //
+    // This matches what LLVM does, see:
+    // <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
     let min = match (os, arch, abi) {
-        // Use 11.0 on Aarch64 as that's the earliest version with M1 support.
         ("macos", Arch::Arm64 | Arch::Arm64e, _) => (11, 0, 0),
-        ("ios", Arch::Arm64e, _) => (14, 0, 0),
+        ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::MacCatalyst) => (14, 0, 0),
+        ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0),
+        ("ios", Arch::Arm64e, TargetAbi::Normal) => (14, 0, 0),
         // Mac Catalyst defaults to 13.1 in Clang.
         ("ios", _, TargetAbi::MacCatalyst) => (13, 1, 0),
+        ("tvos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0),
+        ("watchos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (7, 0, 0),
         _ => os_min,
     };
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index c3e7f74c564..f12e3e595ad 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -855,6 +855,43 @@ impl ToJson for RelroLevel {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Hash)]
+pub enum SmallDataThresholdSupport {
+    None,
+    DefaultForArch,
+    LlvmModuleFlag(StaticCow<str>),
+    LlvmArg(StaticCow<str>),
+}
+
+impl FromStr for SmallDataThresholdSupport {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        if s == "none" {
+            Ok(Self::None)
+        } else if s == "default-for-arch" {
+            Ok(Self::DefaultForArch)
+        } else if let Some(flag) = s.strip_prefix("llvm-module-flag=") {
+            Ok(Self::LlvmModuleFlag(flag.to_string().into()))
+        } else if let Some(arg) = s.strip_prefix("llvm-arg=") {
+            Ok(Self::LlvmArg(arg.to_string().into()))
+        } else {
+            Err(())
+        }
+    }
+}
+
+impl ToJson for SmallDataThresholdSupport {
+    fn to_json(&self) -> Value {
+        match self {
+            Self::None => "none".to_json(),
+            Self::DefaultForArch => "default-for-arch".to_json(),
+            Self::LlvmModuleFlag(flag) => format!("llvm-module-flag={flag}").to_json(),
+            Self::LlvmArg(arg) => format!("llvm-arg={arg}").to_json(),
+        }
+    }
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Hash)]
 pub enum MergeFunctions {
     Disabled,
@@ -2392,6 +2429,9 @@ pub struct TargetOptions {
 
     /// Whether the target supports XRay instrumentation.
     pub supports_xray: bool,
+
+    /// Whether the targets supports -Z small-data-threshold
+    small_data_threshold_support: SmallDataThresholdSupport,
 }
 
 /// Add arguments for the given flavor and also for its "twin" flavors
@@ -2609,6 +2649,7 @@ impl Default for TargetOptions {
             entry_name: "main".into(),
             entry_abi: Conv::C,
             supports_xray: false,
+            small_data_threshold_support: SmallDataThresholdSupport::DefaultForArch,
         }
     }
 }
@@ -2884,6 +2925,15 @@ impl Target {
                     Some(Ok(()))
                 })).unwrap_or(Ok(()))
             } );
+            ($key_name:ident, SmallDataThresholdSupport) => ( {
+                obj.remove("small-data-threshold-support").and_then(|o| o.as_str().and_then(|s| {
+                    match s.parse::<SmallDataThresholdSupport>() {
+                        Ok(support) => base.small_data_threshold_support = support,
+                        _ => return Some(Err(format!("'{s}' is not a valid value for small-data-threshold-support."))),
+                    }
+                    Some(Ok(()))
+                })).unwrap_or(Ok(()))
+            } );
             ($key_name:ident, PanicStrategy) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
@@ -3321,6 +3371,7 @@ impl Target {
         key!(supported_sanitizers, SanitizerSet)?;
         key!(generate_arange_section, bool);
         key!(supports_stack_protector, bool);
+        key!(small_data_threshold_support, SmallDataThresholdSupport)?;
         key!(entry_name);
         key!(entry_abi, Conv)?;
         key!(supports_xray, bool);
@@ -3415,6 +3466,30 @@ impl Target {
             }
         }
     }
+
+    /// Return the target's small data threshold support, converting
+    /// `DefaultForArch` into a concrete value.
+    pub fn small_data_threshold_support(&self) -> SmallDataThresholdSupport {
+        match &self.options.small_data_threshold_support {
+            // Avoid having to duplicate the small data support in every
+            // target file by supporting a default value for each
+            // architecture.
+            SmallDataThresholdSupport::DefaultForArch => match self.arch.as_ref() {
+                "mips" | "mips64" | "mips32r6" => {
+                    SmallDataThresholdSupport::LlvmArg("mips-ssection-threshold".into())
+                }
+                "hexagon" => {
+                    SmallDataThresholdSupport::LlvmArg("hexagon-small-data-threshold".into())
+                }
+                "m68k" => SmallDataThresholdSupport::LlvmArg("m68k-ssection-threshold".into()),
+                "riscv32" | "riscv64" => {
+                    SmallDataThresholdSupport::LlvmModuleFlag("SmallDataLimit".into())
+                }
+                _ => SmallDataThresholdSupport::None,
+            },
+            s => s.clone(),
+        }
+    }
 }
 
 impl ToJson for Target {
@@ -3577,6 +3652,7 @@ impl ToJson for Target {
         target_option_val!(c_enum_min_bits);
         target_option_val!(generate_arange_section);
         target_option_val!(supports_stack_protector);
+        target_option_val!(small_data_threshold_support);
         target_option_val!(entry_name);
         target_option_val!(entry_abi);
         target_option_val!(supports_xray);
diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
index 67afe35bee4..3e27f1f899b 100644
--- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
@@ -1,10 +1,8 @@
 use crate::spec::base::apple::{base, Arch, TargetAbi};
-use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};
+use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let (mut opts, llvm_target, arch) = base("macos", Arch::I686, TargetAbi::Normal);
-    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
-
+    let (opts, llvm_target, arch) = base("macos", Arch::I686, TargetAbi::Normal);
     Target {
         llvm_target,
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
index d33c7af92c6..0bcbf655bd8 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, CodeModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
     Target {
@@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         arch: "loongarch64".into(),
         options: TargetOptions {
+            code_model: Some(CodeModel::Medium),
             cpu: "generic".into(),
             features: "+f,+d".into(),
             llvm_abiname: "lp64d".into(),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
index 5540e71ad4f..223d979a06f 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs
@@ -1,4 +1,4 @@
-use crate::spec::{base, Target, TargetOptions};
+use crate::spec::{base, CodeModel, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
     Target {
@@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         arch: "loongarch64".into(),
         options: TargetOptions {
+            code_model: Some(CodeModel::Medium),
             cpu: "generic".into(),
             features: "+f,+d".into(),
             llvm_abiname: "lp64d".into(),
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
index 56285190268..db527c8b636 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs
@@ -23,7 +23,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            code_model: Some(CodeModel::Small),
+            code_model: Some(CodeModel::Medium),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
index 7e57715ce7a..221ca02fe3e 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs
@@ -24,7 +24,7 @@ pub(crate) fn target() -> Target {
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            code_model: Some(CodeModel::Small),
+            code_model: Some(CodeModel::Medium),
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
index e7f14aa9209..4304dfc3f68 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
@@ -1,9 +1,8 @@
 use crate::spec::base::apple::{base, Arch, TargetAbi};
-use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
+use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetAbi::Normal);
-    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
+    let (opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetAbi::Normal);
     Target {
         llvm_target,
         metadata: crate::spec::TargetMetadata {
diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
index f44bc660a62..9fb5a46187a 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
@@ -1,11 +1,10 @@
 use crate::spec::base::apple::{base, Arch, TargetAbi};
-use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
+use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
     let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64h, TargetAbi::Normal);
     opts.max_atomic_width = Some(128);
     opts.frame_pointer = FramePointer::Always;
-    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
     opts.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 65d21518491..d486416f22a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -1323,23 +1323,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 label_or_note(span, terr.to_string(self.tcx));
                 label_or_note(sp, msg);
             }
-        } else {
-            if let Some(values) = values
-                && let Some((e, f)) = values.ty()
-                && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr
-            {
-                let e = self.tcx.erase_regions(e);
-                let f = self.tcx.erase_regions(f);
-                let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
-                let found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
-                if expected == found {
-                    label_or_note(span, terr.to_string(self.tcx));
-                } else {
-                    label_or_note(span, Cow::from(format!("expected {expected}, found {found}")));
-                }
-            } else {
+        } else if let Some(values) = values
+            && let Some((e, f)) = values.ty()
+            && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr
+        {
+            let e = self.tcx.erase_regions(e);
+            let f = self.tcx.erase_regions(f);
+            let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
+            let found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
+            if expected == found {
                 label_or_note(span, terr.to_string(self.tcx));
+            } else {
+                label_or_note(span, Cow::from(format!("expected {expected}, found {found}")));
             }
+        } else {
+            label_or_note(span, terr.to_string(self.tcx));
         }
 
         if let Some((expected, found, path)) = expected_found {
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 45e157b1080..b13aede509a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -3237,16 +3237,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 // then the tuple must be the one containing capture types.
                 let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) {
                     false
+                } else if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code {
+                    let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
+                    let nested_ty = parent_trait_ref.skip_binder().self_ty();
+                    matches!(nested_ty.kind(), ty::Coroutine(..))
+                        || matches!(nested_ty.kind(), ty::Closure(..))
                 } else {
-                    if let ObligationCauseCode::BuiltinDerived(data) = &*data.parent_code {
-                        let parent_trait_ref =
-                            self.resolve_vars_if_possible(data.parent_trait_pred);
-                        let nested_ty = parent_trait_ref.skip_binder().self_ty();
-                        matches!(nested_ty.kind(), ty::Coroutine(..))
-                            || matches!(nested_ty.kind(), ty::Closure(..))
-                    } else {
-                        false
-                    }
+                    false
                 };
 
                 if !is_upvar_tys_infer_tuple {
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index f5f36f40f7e..cfc73e2e47e 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -302,7 +302,7 @@ fn fulfillment_error_for_stalled<'tcx>(
             Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
                 FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
                 // Don't look into overflows because we treat overflows weirdly anyways.
-                // In `instantiate_response_discarding_overflow` we set `has_changed = false`,
+                // We discard the inference constraints from overflowing goals, so
                 // recomputing the goal again during `find_best_leaf_obligation` may apply
                 // inference guidance that makes other goals go from ambig -> pass, for example.
                 //
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index c8811bc37b3..de1d4ef15ac 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -35,8 +35,10 @@ where
         if infcx.next_trait_solver() {
             Box::new(NextFulfillmentCtxt::new(infcx))
         } else {
+            let new_solver_globally =
+                infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally);
             assert!(
-                !infcx.tcx.next_trait_solver_globally(),
+                !new_solver_globally,
                 "using old solver even though new solver is enabled globally"
             );
             Box::new(FulfillmentContext::new(infcx))
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 630acc91fbe..c27a9285b3a 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -408,7 +408,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
             debug!("opt_normalize_projection_type: found error");
             let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
             obligations.extend(result.obligations);
-            return Ok(Some(result.value.into()));
+            return Ok(Some(result.value));
         }
     }
 
@@ -478,7 +478,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
             }
             let result = normalize_to_error(selcx, param_env, projection_term, cause, depth);
             obligations.extend(result.obligations);
-            Ok(Some(result.value.into()))
+            Ok(Some(result.value))
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 77efc2fc2db..3e3589538c7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -426,13 +426,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     } else if kind == ty::ClosureKind::FnOnce {
                         candidates.vec.push(ClosureCandidate { is_const });
                     }
+                } else if kind == ty::ClosureKind::FnOnce {
+                    candidates.vec.push(ClosureCandidate { is_const });
                 } else {
-                    if kind == ty::ClosureKind::FnOnce {
-                        candidates.vec.push(ClosureCandidate { is_const });
-                    } else {
-                        // This stays ambiguous until kind+upvars are determined.
-                        candidates.ambiguous = true;
-                    }
+                    // This stays ambiguous until kind+upvars are determined.
+                    candidates.ambiguous = true;
                 }
             }
             ty::Infer(ty::TyVar(_)) => {
@@ -513,10 +511,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // then there's nothing else to check.
         if let Some(closure_kind) = self_ty.to_opt_closure_kind()
             && let Some(goal_kind) = target_kind_ty.to_opt_closure_kind()
+            && closure_kind.extends(goal_kind)
         {
-            if closure_kind.extends(goal_kind) {
-                candidates.vec.push(AsyncFnKindHelperCandidate);
-            }
+            candidates.vec.push(AsyncFnKindHelperCandidate);
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 241c3a3d141..f5cd7273ca2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1334,16 +1334,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return;
         }
 
-        if self.can_use_global_caches(param_env) {
-            if !trait_pred.has_infer() {
-                debug!(?trait_pred, ?result, "insert_evaluation_cache global");
-                // This may overwrite the cache with the same value
-                // FIXME: Due to #50507 this overwrites the different values
-                // This should be changed to use HashMapExt::insert_same
-                // when that is fixed
-                self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
-                return;
-            }
+        if self.can_use_global_caches(param_env) && !trait_pred.has_infer() {
+            debug!(?trait_pred, ?result, "insert_evaluation_cache global");
+            // This may overwrite the cache with the same value
+            // FIXME: Due to #50507 this overwrites the different values
+            // This should be changed to use HashMapExt::insert_same
+            // when that is fixed
+            self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
+            return;
         }
 
         debug!(?trait_pred, ?result, "insert_evaluation_cache");
@@ -1584,13 +1582,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         if self.can_use_global_caches(param_env) {
             if let Err(Overflow(OverflowError::Canonical)) = candidate {
                 // Don't cache overflow globally; we only produce this in certain modes.
-            } else if !pred.has_infer() {
-                if !candidate.has_infer() {
-                    debug!(?pred, ?candidate, "insert_candidate_cache global");
-                    // This may overwrite the cache with the same value.
-                    tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
-                    return;
-                }
+            } else if !pred.has_infer() && !candidate.has_infer() {
+                debug!(?pred, ?candidate, "insert_candidate_cache global");
+                // This may overwrite the cache with the same value.
+                tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
+                return;
             }
         }
 
@@ -1980,10 +1976,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 // impls have to be always applicable, meaning that the only allowed
                 // region constraints may be constraints also present on the default impl.
                 let tcx = self.tcx();
-                if other.evaluation.must_apply_modulo_regions() {
-                    if tcx.specializes((other_def, victim_def)) {
-                        return DropVictim::Yes;
-                    }
+                if other.evaluation.must_apply_modulo_regions()
+                    && tcx.specializes((other_def, victim_def))
+                {
+                    return DropVictim::Yes;
                 }
 
                 match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index e899284674c..6b24929467b 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -143,10 +143,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         match origin {
             rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
             rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
-                if !in_assoc_ty {
-                    if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
-                        return;
-                    }
+                if !in_assoc_ty && !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
+                    return;
                 }
             }
         }
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 96998d2ec9f..a0f7658212f 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -117,7 +117,8 @@ impl<I: Interner, P> Goal<I, P> {
 /// Why a specific goal has to be proven.
 ///
 /// This is necessary as we treat nested goals different depending on
-/// their source.
+/// their source. This is currently mostly used by proof tree visitors
+/// but will be used by cycle handling in the future.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
 pub enum GoalSource {
@@ -126,13 +127,6 @@ pub enum GoalSource {
     ///
     /// FIXME(-Znext-solver=coinductive): Explain how and why this
     /// changes whether cycles are coinductive.
-    ///
-    /// This also impacts whether we erase constraints on overflow.
-    /// Erasing constraints is generally very useful for perf and also
-    /// results in better error messages by avoiding spurious errors.
-    /// We do not erase overflow constraints in `normalizes-to` goals unless
-    /// they are from an impl where-clause. This is necessary due to
-    /// backwards compatibility, cc trait-system-refactor-initiatitive#70.
     ImplWhereBound,
     /// Instantiating a higher-ranked goal and re-proving it.
     InstantiateHigherRanked,