about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs117
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs14
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs8
-rw-r--r--compiler/rustc_const_eval/src/errors.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs36
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs9
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl1
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs15
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs8
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/middle/exported_symbols.rs2
-rw-r--r--compiler/rustc_middle/src/mir/graphviz.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs3
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs38
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs6
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs36
-rw-r--r--compiler/rustc_middle/src/query/erase.rs2
-rw-r--r--compiler/rustc_middle/src/query/keys.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs12
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs49
-rw-r--r--compiler/rustc_middle/src/traits/solve.rs30
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs204
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs74
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs6
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs5
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs89
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs244
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs192
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs106
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs38
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs32
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs55
-rw-r--r--compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs2
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs6
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs34
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs64
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/lib.rs6
-rw-r--r--compiler/rustc_privacy/src/lib.rs8
-rw-r--r--compiler/rustc_resolve/src/ident.rs25
-rw-r--r--compiler/rustc_resolve/src/late.rs142
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs12
-rw-r--r--compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/builder.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs6
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs28
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs6
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs14
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs16
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs66
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs24
-rw-r--r--compiler/rustc_trait_selection/src/solve/select.rs (renamed from compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs)0
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs12
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs28
-rw-r--r--compiler/rustc_type_ir/src/interner.rs7
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/opaque_ty.rs51
-rw-r--r--compiler/rustc_type_ir/src/region_kind.rs2
-rw-r--r--compiler/rustc_type_ir/src/solve.rs91
-rw-r--r--library/core/src/error.rs2
-rw-r--r--library/core/src/future/async_drop.rs24
-rw-r--r--library/core/src/future/mod.rs2
-rw-r--r--library/core/src/num/int_macros.rs10
-rw-r--r--library/core/src/ptr/mod.rs12
-rw-r--r--library/std/src/os/hermit/io/mod.rs15
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--src/bootstrap/src/lib.rs37
-rw-r--r--src/bootstrap/src/utils/helpers.rs10
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs2
-rw-r--r--src/tools/run-make-support/src/command.rs44
-rw-r--r--src/tools/run-make-support/src/lib.rs53
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt6
-rw-r--r--tests/codegen/error-provide.rs50
-rw-r--r--tests/crashes/126062.rs11
-rw-r--r--tests/crashes/126376.rs14
-rw-r--r--tests/crashes/126385.rs10
-rw-r--r--tests/crashes/126389.rs15
-rw-r--r--tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs1
-rw-r--r--tests/run-make/clear-error-blank-output/blank.rs (renamed from tests/run-make/issue-26092/blank.rs)0
-rw-r--r--tests/run-make/clear-error-blank-output/rmake.rs13
-rw-r--r--tests/run-make/const_fn_mir/rmake.rs2
-rw-r--r--tests/run-make/inaccessible-temp-dir/Makefile32
-rw-r--r--tests/run-make/inaccessible-temp-dir/rmake.rs38
-rw-r--r--tests/run-make/issue-10971-temps-dir/Makefile10
-rw-r--r--tests/run-make/issue-26092/Makefile6
-rw-r--r--tests/run-make/issue-47551/Makefile3
-rw-r--r--tests/run-make/link-arg/Makefile5
-rw-r--r--tests/run-make/link-arg/rmake.rs20
-rw-r--r--tests/run-make/link-dedup/Makefile12
-rw-r--r--tests/run-make/link-dedup/rmake.rs24
-rw-r--r--tests/run-make/output-with-hyphens/Makefile8
-rw-r--r--tests/run-make/output-with-hyphens/rmake.rs17
-rw-r--r--tests/run-make/parallel-rustc-no-overwrite/rmake.rs25
-rw-r--r--tests/ui/associated-consts/double-elided.rs8
-rw-r--r--tests/ui/associated-consts/double-elided.stderr47
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs2
-rw-r--r--tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr16
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs10
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr12
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs17
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr20
-rw-r--r--tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs14
-rw-r--r--tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr34
-rw-r--r--tests/ui/closures/wrong-closure-arg-suggestion-125325.rs29
-rw-r--r--tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr28
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr19
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never-windows.rs58
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr11
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr12
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.rs20
-rw-r--r--tests/ui/const-generics/generic_arg_infer/issue-91614.stderr2
-rw-r--r--tests/ui/consts/assoc-const-elided-lifetime.stderr12
-rw-r--r--tests/ui/consts/static-default-lifetime/elided-lifetime.rs22
-rw-r--r--tests/ui/consts/static-default-lifetime/elided-lifetime.stderr59
-rw-r--r--tests/ui/consts/static-default-lifetime/generic-associated-const.rs19
-rw-r--r--tests/ui/consts/static-default-lifetime/generic-associated-const.stderr46
-rw-r--r--tests/ui/consts/static-default-lifetime/inner-item.rs21
-rw-r--r--tests/ui/consts/static-default-lifetime/static-trait-impl.rs20
-rw-r--r--tests/ui/consts/static-default-lifetime/static-trait-impl.stderr45
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-3.rs19
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-3.stderr23
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-4.rs20
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-4.stderr23
-rw-r--r--tests/ui/inference/need_type_info/type-alias-indirect.stderr2
-rw-r--r--tests/ui/inference/need_type_info/type-alias.stderr6
-rw-r--r--tests/ui/privacy/no-ice-on-inference-failure.rs (renamed from tests/crashes/122736.rs)2
-rw-r--r--tests/ui/privacy/no-ice-on-inference-failure.stderr27
-rw-r--r--tests/ui/statics/const_generics.rs26
-rw-r--r--tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr56
-rw-r--r--tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr46
-rw-r--r--tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs8
-rw-r--r--tests/ui/suggestions/mut-borrow-needed-by-trait.rs1
-rw-r--r--tests/ui/suggestions/mut-borrow-needed-by-trait.stderr16
166 files changed, 2085 insertions, 1532 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 2297924c7f3..305da6a3550 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -97,7 +97,6 @@ Cargo
 - [Prevent dashes in `lib.name`, always normalizing to `_`.](https://github.com/rust-lang/cargo/pull/12783/)
 - [Stabilize MSRV-aware version requirement selection in `cargo add`.](https://github.com/rust-lang/cargo/pull/13608/)
 - [Switch to using `gitoxide` by default for listing files.](https://github.com/rust-lang/cargo/pull/13696/)
-- [Error on `[project]` in Edition 2024; `cargo fix --edition` will change it to `[package]`.](https://github.com/rust-lang/cargo/pull/13747/)
 
 <a id="1.79.0-Rustdoc"></a>
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index df1a1411cf5..9fd23bc94cf 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -8,7 +8,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::{self as hir, BindingMode, ByRef, Node};
 use rustc_middle::bug;
 use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
-use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, Upcast};
+use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Upcast};
 use rustc_middle::{
     hir::place::PlaceBase,
     mir::{self, BindingForm, Local, LocalDecl, LocalInfo, LocalKind, Location},
@@ -937,56 +937,81 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let node = self.infcx.tcx.hir_node(fn_call_id);
         let def_id = hir.enclosing_body_owner(fn_call_id);
         let mut look_at_return = true;
-        // If we can detect the expression to be an `fn` call where the closure was an argument,
-        // we point at the `fn` definition argument...
-        if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Call(func, args), .. }) = node {
-            let arg_pos = args
+
+        // If the HIR node is a function or method call gets the def ID
+        // of the called function or method and the span and args of the call expr
+        let get_call_details = || {
+            let hir::Node::Expr(hir::Expr { hir_id, kind, .. }) = node else {
+                return None;
+            };
+
+            let typeck_results = self.infcx.tcx.typeck(def_id);
+
+            match kind {
+                hir::ExprKind::Call(expr, args) => {
+                    if let Some(ty::FnDef(def_id, _)) =
+                        typeck_results.node_type_opt(expr.hir_id).as_ref().map(|ty| ty.kind())
+                    {
+                        Some((*def_id, expr.span, *args))
+                    } else {
+                        None
+                    }
+                }
+                hir::ExprKind::MethodCall(_, _, args, span) => {
+                    if let Some(def_id) = typeck_results.type_dependent_def_id(*hir_id) {
+                        Some((def_id, *span, *args))
+                    } else {
+                        None
+                    }
+                }
+                _ => None,
+            }
+        };
+
+        // If we can detect the expression to be an function or method call where the closure was an argument,
+        // we point at the function or method definition argument...
+        if let Some((callee_def_id, call_span, call_args)) = get_call_details() {
+            let arg_pos = call_args
                 .iter()
                 .enumerate()
                 .filter(|(_, arg)| arg.hir_id == closure_id)
                 .map(|(pos, _)| pos)
                 .next();
-            let tables = self.infcx.tcx.typeck(def_id);
-            if let Some(ty::FnDef(def_id, _)) =
-                tables.node_type_opt(func.hir_id).as_ref().map(|ty| ty.kind())
-            {
-                let arg = match hir.get_if_local(*def_id) {
-                    Some(
-                        hir::Node::Item(hir::Item {
-                            ident, kind: hir::ItemKind::Fn(sig, ..), ..
-                        })
-                        | hir::Node::TraitItem(hir::TraitItem {
-                            ident,
-                            kind: hir::TraitItemKind::Fn(sig, _),
-                            ..
+
+            let arg = match hir.get_if_local(callee_def_id) {
+                Some(
+                    hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn(sig, ..), .. })
+                    | hir::Node::TraitItem(hir::TraitItem {
+                        ident,
+                        kind: hir::TraitItemKind::Fn(sig, _),
+                        ..
+                    })
+                    | hir::Node::ImplItem(hir::ImplItem {
+                        ident,
+                        kind: hir::ImplItemKind::Fn(sig, _),
+                        ..
+                    }),
+                ) => Some(
+                    arg_pos
+                        .and_then(|pos| {
+                            sig.decl.inputs.get(
+                                pos + if sig.decl.implicit_self.has_implicit_self() {
+                                    1
+                                } else {
+                                    0
+                                },
+                            )
                         })
-                        | hir::Node::ImplItem(hir::ImplItem {
-                            ident,
-                            kind: hir::ImplItemKind::Fn(sig, _),
-                            ..
-                        }),
-                    ) => Some(
-                        arg_pos
-                            .and_then(|pos| {
-                                sig.decl.inputs.get(
-                                    pos + if sig.decl.implicit_self.has_implicit_self() {
-                                        1
-                                    } else {
-                                        0
-                                    },
-                                )
-                            })
-                            .map(|arg| arg.span)
-                            .unwrap_or(ident.span),
-                    ),
-                    _ => None,
-                };
-                if let Some(span) = arg {
-                    err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
-                    err.span_label(func.span, "expects `Fn` instead of `FnMut`");
-                    err.span_label(closure_span, "in this closure");
-                    look_at_return = false;
-                }
+                        .map(|arg| arg.span)
+                        .unwrap_or(ident.span),
+                ),
+                _ => None,
+            };
+            if let Some(span) = arg {
+                err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
+                err.span_label(call_span, "expects `Fn` instead of `FnMut`");
+                err.span_label(closure_span, "in this closure");
+                look_at_return = false;
             }
         }
 
@@ -1020,7 +1045,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     fn suggest_using_iter_mut(&self, err: &mut Diag<'_>) {
         let source = self.body.source;
         let hir = self.infcx.tcx.hir();
-        if let InstanceDef::Item(def_id) = source.instance
+        if let InstanceKind::Item(def_id) = source.instance
             && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id)
             && let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind
             && let Node::Expr(expr) = self.infcx.tcx.parent_hir_node(*hir_id)
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 2cf548e28b1..77fb9fb4315 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -628,9 +628,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     | GenericArgKind::Const(_),
                     _,
                 ) => {
-                    // This was previously a `span_delayed_bug` and could be
-                    // reached by the test for #82126, but no longer.
-                    self.dcx().span_bug(
+                    self.dcx().span_delayed_bug(
                         hir_arg.span(),
                         format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
                     );
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index bd5a8876905..695dbaf2804 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -399,7 +399,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
         }
 
         match instance.def {
-            InstanceDef::Intrinsic(_) => {
+            InstanceKind::Intrinsic(_) => {
                 match crate::intrinsics::codegen_intrinsic_call(
                     fx,
                     instance,
@@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
                     Err(instance) => Some(instance),
                 }
             }
-            InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => {
+            InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => {
                 // empty drop glue - a nop.
                 let dest = target.expect("Non terminating drop_in_place_real???");
                 let ret_block = fx.get_block(dest);
@@ -494,7 +494,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
 
     let (func_ref, first_arg_override) = match instance {
         // Trait object call
-        Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => {
+        Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => {
             if fx.clif_comments.enabled() {
                 let nop_inst = fx.bcx.ins().nop();
                 fx.add_comment(
@@ -598,7 +598,7 @@ pub(crate) fn codegen_drop<'tcx>(
     let ty = drop_place.layout().ty;
     let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx);
 
-    if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) =
+    if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) =
         drop_instance.def
     {
         // we don't actually need to drop anything
@@ -630,7 +630,7 @@ pub(crate) fn codegen_drop<'tcx>(
                 // FIXME(eddyb) perhaps move some of this logic into
                 // `Instance::resolve_drop_in_place`?
                 let virtual_drop = Instance {
-                    def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
+                    def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
                     args: drop_instance.args,
                 };
                 let fn_abi =
@@ -673,7 +673,7 @@ pub(crate) fn codegen_drop<'tcx>(
                 fx.bcx.switch_to_block(continued);
 
                 let virtual_drop = Instance {
-                    def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
+                    def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0),
                     args: drop_instance.args,
                 };
                 let fn_abi =
@@ -684,7 +684,7 @@ pub(crate) fn codegen_drop<'tcx>(
                 fx.bcx.ins().call_indirect(sig, drop_fn, &[data]);
             }
             _ => {
-                assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
+                assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));
 
                 let fn_abi =
                     RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty());
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index a53598018f4..87c5da3b7c3 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -50,7 +50,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
 ) -> CValue<'tcx> {
     let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) {
         let instance = ty::Instance {
-            def: ty::InstanceDef::ThreadLocalShim(def_id),
+            def: ty::InstanceKind::ThreadLocalShim(def_id),
             args: ty::GenericArgs::empty(),
         };
         let func_ref = fx.get_function_ref(instance);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index cafdc051db5..b21c559e668 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1261,7 +1261,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
         }
 
         // Unimplemented intrinsics must have a fallback body. The fallback body is obtained
-        // by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`.
+        // by converting the `InstanceKind::Intrinsic` to an `InstanceKind::Item`.
         _ => {
             let intrinsic = fx.tcx.intrinsic(instance.def_id()).unwrap();
             if intrinsic.must_be_overridden {
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 0fea3fd4253..2edb34e7c20 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -98,7 +98,7 @@ mod prelude {
     pub(crate) use rustc_middle::mir::{self, *};
     pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
     pub(crate) use rustc_middle::ty::{
-        self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, UintTy,
+        self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy,
     };
     pub(crate) use rustc_span::Span;
     pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index a6df8950b35..1d61c156409 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -310,7 +310,7 @@ fn exported_symbols_provider_local(
 
     if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() {
         use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
-        use rustc_middle::ty::InstanceDef;
+        use rustc_middle::ty::InstanceKind;
 
         // Normally, we require that shared monomorphizations are not hidden,
         // because if we want to re-use a monomorphization from a Rust dylib, it
@@ -337,7 +337,7 @@ fn exported_symbols_provider_local(
             }
 
             match *mono_item {
-                MonoItem::Fn(Instance { def: InstanceDef::Item(def), args }) => {
+                MonoItem::Fn(Instance { def: InstanceKind::Item(def), args }) => {
                     if args.non_erasable_generics(tcx, def).next().is_some() {
                         let symbol = ExportedSymbol::Generic(def, args);
                         symbols.push((
@@ -350,7 +350,7 @@ fn exported_symbols_provider_local(
                         ));
                     }
                 }
-                MonoItem::Fn(Instance { def: InstanceDef::DropGlue(def_id, Some(ty)), args }) => {
+                MonoItem::Fn(Instance { def: InstanceKind::DropGlue(def_id, Some(ty)), args }) => {
                     // A little sanity-check
                     debug_assert_eq!(
                         args.non_erasable_generics(tcx, def_id).next(),
@@ -366,7 +366,7 @@ fn exported_symbols_provider_local(
                     ));
                 }
                 MonoItem::Fn(Instance {
-                    def: InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty)),
+                    def: InstanceKind::AsyncDropGlueCtorShim(def_id, Some(ty)),
                     args,
                 }) => {
                     // A little sanity-check
@@ -556,7 +556,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
             rustc_symbol_mangling::symbol_name_for_instance_in_crate(
                 tcx,
                 ty::Instance {
-                    def: ty::InstanceDef::ThreadLocalShim(def_id),
+                    def: ty::InstanceKind::ThreadLocalShim(def_id),
                     args: ty::GenericArgs::empty(),
                 },
                 instantiating_crate,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index bd9704b37ae..57138d3b9db 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -510,7 +510,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let ty = self.monomorphize(ty);
         let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
 
-        if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
+        if let ty::InstanceKind::DropGlue(_, None) = drop_fn.def {
             // we don't actually need to drop anything.
             return helper.funclet_br(self, bx, target, mergeable_succ);
         }
@@ -541,7 +541,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 //                \-------/
                 //
                 let virtual_drop = Instance {
-                    def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
+                    def: ty::InstanceKind::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
                     args: drop_fn.args,
                 };
                 debug!("ty = {:?}", ty);
@@ -583,7 +583,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 //
                 // SO THEN WE CAN USE THE ABOVE CODE.
                 let virtual_drop = Instance {
-                    def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
+                    def: ty::InstanceKind::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function
                     args: drop_fn.args,
                 };
                 debug!("ty = {:?}", ty);
@@ -855,7 +855,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let def = instance.map(|i| i.def);
 
         if let Some(
-            ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None),
+            ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None),
         ) = def
         {
             // Empty drop glue; a no-op.
@@ -871,7 +871,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Handle intrinsics old codegen wants Expr's for, ourselves.
         let intrinsic = match def {
-            Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()),
+            Some(ty::InstanceKind::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()),
             _ => None,
         };
 
@@ -1026,7 +1026,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         'make_args: for (i, arg) in first_args.iter().enumerate() {
             let mut op = self.codegen_operand(bx, &arg.node);
 
-            if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
+            if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, def) {
                 match op.val {
                     Pair(data_ptr, meta) => {
                         // In the case of Rc<Self>, we need to explicitly pass a
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index ad6b3f1159d..3dc7dc35511 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -704,7 +704,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id)
                 {
                     let instance = ty::Instance {
-                        def: ty::InstanceDef::ThreadLocalShim(def_id),
+                        def: ty::InstanceKind::ThreadLocalShim(def_id),
                         args: ty::GenericArgs::empty(),
                     };
                     let fn_ptr = bx.get_fn_addr(instance);
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 2dbeb7d5e0c..cb5aac7e560 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -399,7 +399,6 @@ const_eval_unwind_past_top =
 
 ## The `front_matter`s here refer to either `const_eval_front_matter_invalid_value` or `const_eval_front_matter_invalid_value_with_path`.
 ## (We'd love to sort this differently to make that more clear but tidy won't let us...)
-const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant
 const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty}
 
 const_eval_validation_const_ref_to_extern = {$front_matter}: encountered reference to `extern` static in `const`
@@ -454,7 +453,6 @@ const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but
 const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers
 const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected}
 const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
-const_eval_validation_ref_to_static = {$front_matter}: encountered a reference pointing to a static variable in a constant
 const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
 const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})
 const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 0818d9425e2..ab60cc37920 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
-use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt};
+use rustc_middle::ty::{Instance, InstanceKind, TypeVisitableExt};
 use rustc_mir_dataflow::Analysis;
 use rustc_span::{sym, Span, Symbol, DUMMY_SP};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
@@ -769,7 +769,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                         if let Ok(Some(instance)) =
                             Instance::resolve(tcx, param_env, callee, fn_args)
-                            && let InstanceDef::Item(def) = instance.def
+                            && let InstanceKind::Item(def) = instance.def
                         {
                             // Resolve a trait method call to its concrete implementation, which may be in a
                             // `const` trait impl. This is only used for the const stability check below, since
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 4b8145eb485..c60df06bb0e 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -289,7 +289,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
 
     // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
     // Catch such calls and evaluate them instead of trying to load a constant's MIR.
-    if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
+    if let ty::InstanceKind::Intrinsic(def_id) = key.value.instance.def {
         let ty = key.value.instance.ty(tcx, key.param_env);
         let ty::FnDef(_, args) = ty.kind() else {
             bug!("intrinsic with type {:?}", ty);
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index d3631e0d723..99276bac035 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -398,10 +398,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
 
     fn load_mir(
         ecx: &InterpCx<'tcx, Self>,
-        instance: ty::InstanceDef<'tcx>,
+        instance: ty::InstanceKind<'tcx>,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
         match instance {
-            ty::InstanceDef::Item(def) => Ok(ecx.tcx.mir_for_ctfe(def)),
+            ty::InstanceKind::Item(def) => Ok(ecx.tcx.mir_for_ctfe(def)),
             _ => Ok(ecx.tcx.instance_mir(instance)),
         }
     }
@@ -424,7 +424,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
         };
 
         // Only check non-glue functions
-        if let ty::InstanceDef::Item(def) = instance.def {
+        if let ty::InstanceKind::Item(def) = instance.def {
             // Execution might have wandered off into other crates, so we cannot do a stability-
             // sensitive check here. But we can at least rule out functions that are not const at
             // all. That said, we have to allow calling functions inside a trait marked with
@@ -540,7 +540,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
                     );
                 }
                 return Ok(Some(ty::Instance {
-                    def: ty::InstanceDef::Item(instance.def_id()),
+                    def: ty::InstanceKind::Item(instance.def_id()),
                     args: instance.args,
                 }));
             }
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index e5ea4c3442e..91d17fdd895 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -640,9 +640,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
                 const_eval_validation_ref_to_uninhabited
             }
 
-            PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static,
-            PtrToStatic { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_ref_to_static,
-
             PointerAsInt { .. } => const_eval_validation_pointer_as_int,
             PartialPointer => const_eval_validation_partial_pointer,
             ConstRefToMutable => const_eval_validation_const_ref_to_mutable,
@@ -807,7 +804,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
                 );
             }
             NullPtr { .. }
-            | PtrToStatic { .. }
             | ConstRefToMutable
             | ConstRefToExtern
             | MutableRefToImmutable
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 4d93038a81e..86325c5ae24 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -562,7 +562,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     pub fn load_mir(
         &self,
-        instance: ty::InstanceDef<'tcx>,
+        instance: ty::InstanceKind<'tcx>,
         promoted: Option<mir::Promoted>,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
         trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 4ae0aca5a0c..e91ab7c1791 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -177,7 +177,7 @@ pub trait Machine<'tcx>: Sized {
     /// constants, ...
     fn load_mir(
         ecx: &InterpCx<'tcx, Self>,
-        instance: ty::InstanceDef<'tcx>,
+        instance: ty::InstanceKind<'tcx>,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
         Ok(ecx.tcx.instance_mir(instance))
     }
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 8f76a148679..74521d0f493 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -175,7 +175,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             Drop { place, target, unwind, replace: _ } => {
                 let place = self.eval_place(place)?;
                 let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
-                if let ty::InstanceDef::DropGlue(_, None) = instance.def {
+                if let ty::InstanceKind::DropGlue(_, None) = instance.def {
                     // This is the branch we enter if and only if the dropped type has no drop glue
                     // whatsoever. This can happen as a result of monomorphizing a drop of a
                     // generic. In order to make sure that generic and non-generic code behaves
@@ -550,7 +550,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         };
 
         match instance.def {
-            ty::InstanceDef::Intrinsic(def_id) => {
+            ty::InstanceKind::Intrinsic(def_id) => {
                 assert!(self.tcx.intrinsic(def_id).is_some());
                 // FIXME: Should `InPlace` arguments be reset to uninit?
                 if let Some(fallback) = M::call_intrinsic(
@@ -562,7 +562,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                     unwind,
                 )? {
                     assert!(!self.tcx.intrinsic(fallback.def_id()).unwrap().must_be_overridden);
-                    assert!(matches!(fallback.def, ty::InstanceDef::Item(_)));
+                    assert!(matches!(fallback.def, ty::InstanceKind::Item(_)));
                     return self.eval_fn_call(
                         FnVal::Instance(fallback),
                         (caller_abi, caller_fn_abi),
@@ -576,18 +576,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                     Ok(())
                 }
             }
-            ty::InstanceDef::VTableShim(..)
-            | ty::InstanceDef::ReifyShim(..)
-            | ty::InstanceDef::ClosureOnceShim { .. }
-            | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceDef::CoroutineKindShim { .. }
-            | ty::InstanceDef::FnPtrShim(..)
-            | ty::InstanceDef::DropGlue(..)
-            | ty::InstanceDef::CloneShim(..)
-            | ty::InstanceDef::FnPtrAddrShim(..)
-            | ty::InstanceDef::ThreadLocalShim(..)
-            | ty::InstanceDef::AsyncDropGlueCtorShim(..)
-            | ty::InstanceDef::Item(_) => {
+            ty::InstanceKind::VTableShim(..)
+            | ty::InstanceKind::ReifyShim(..)
+            | ty::InstanceKind::ClosureOnceShim { .. }
+            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | ty::InstanceKind::CoroutineKindShim { .. }
+            | ty::InstanceKind::FnPtrShim(..)
+            | ty::InstanceKind::DropGlue(..)
+            | ty::InstanceKind::CloneShim(..)
+            | ty::InstanceKind::FnPtrAddrShim(..)
+            | ty::InstanceKind::ThreadLocalShim(..)
+            | ty::InstanceKind::AsyncDropGlueCtorShim(..)
+            | ty::InstanceKind::Item(_) => {
                 // We need MIR for this fn
                 let Some((body, instance)) = M::find_mir_or_eval_fn(
                     self,
@@ -786,9 +786,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                     Ok(()) => Ok(()),
                 }
             }
-            // `InstanceDef::Virtual` does not have callable MIR. Calls to `Virtual` instances must be
+            // `InstanceKind::Virtual` does not have callable MIR. Calls to `Virtual` instances must be
             // codegen'd / interpreted as virtual calls through the vtable.
-            ty::InstanceDef::Virtual(def_id, idx) => {
+            ty::InstanceKind::Virtual(def_id, idx) => {
                 let mut args = args.to_vec();
                 // We have to implement all "object safe receivers". So we have to go search for a
                 // pointer or `dyn Trait` type, but it could be wrapped in newtypes. So recursively
@@ -965,7 +965,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         let place = self.force_allocation(place)?;
 
         // We behave a bit different from codegen here.
-        // Codegen creates an `InstanceDef::Virtual` with index 0 (the slot of the drop method) and
+        // Codegen creates an `InstanceKind::Virtual` with index 0 (the slot of the drop method) and
         // then dispatches that to the normal call machinery. However, our call machinery currently
         // only supports calling `VtblEntry::Method`; it would choke on a `MetadataDropInPlace`. So
         // instead we do the virtual call stuff ourselves. It's easier here than in `eval_fn_call`
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index f6537ed6ea9..bbe5e5fe3ed 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -44,7 +44,7 @@ where
                 | ty::CoroutineClosure(def_id, args, ..)
                 | ty::Coroutine(def_id, args, ..)
                 | ty::FnDef(def_id, args) => {
-                    let instance = ty::InstanceDef::Item(def_id);
+                    let instance = ty::InstanceKind::Item(def_id);
                     let unused_params = self.tcx.unused_generic_params(instance);
                     for (index, arg) in args.into_iter().enumerate() {
                         let index = index
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 9531c002829..061afd03062 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -750,16 +750,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Resolves an associated value path into a base type and associated constant, or method
     /// resolution. The newly resolved definition is written into `type_dependent_defs`.
+    #[instrument(level = "trace", skip(self), ret)]
     pub fn resolve_ty_and_res_fully_qualified_call(
         &self,
         qpath: &'tcx QPath<'tcx>,
         hir_id: HirId,
         span: Span,
     ) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
-        debug!(
-            "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
-            qpath, hir_id, span
-        );
         let (ty, qself, item_segment) = match *qpath {
             QPath::Resolved(ref opt_qself, path) => {
                 return (
@@ -1417,10 +1414,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // This also occurs for an enum variant on a type alias.
             let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
             let self_ty = self.normalize(span, self_ty);
-            match self.at(&self.misc(span), self.param_env).eq(
+            match self.at(&self.misc(span), self.param_env).sub(
                 DefineOpaqueTypes::Yes,
-                impl_ty,
                 self_ty,
+                impl_ty,
             ) {
                 Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index d52286d5887..f881d53858a 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -756,7 +756,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
                 || tcx.hir().body_const_context(def_id).is_some()
             {
                 tcx.ensure().mir_drops_elaborated_and_const_checked(def_id);
-                tcx.ensure().unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id()));
+                tcx.ensure().unused_generic_params(ty::InstanceKind::Item(def_id.to_def_id()));
             }
         }
     });
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 043042a492b..da1f36112ab 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -14,6 +14,7 @@ lint_associated_const_elided_lifetime = {$elided ->
         *[false] `'_` cannot be used here
     }
     .suggestion = use the `'static` lifetime
+    .note = cannot automatically infer `'static` because of other lifetimes in scope
 
 lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
     .note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 83640d7210f..290bb5173db 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -319,11 +319,20 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::UnusedQualifications { removal_span } => {
             lints::UnusedQualifications { removal_span }.decorate_lint(diag);
         }
-        BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span } => {
+        BuiltinLintDiag::AssociatedConstElidedLifetime {
+            elided,
+            span: lt_span,
+            lifetimes_in_scope,
+        } => {
             let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span };
             let code = if elided { "'static " } else { "'static" };
-            lints::AssociatedConstElidedLifetime { span: lt_span, code, elided }
-                .decorate_lint(diag);
+            lints::AssociatedConstElidedLifetime {
+                span: lt_span,
+                code,
+                elided,
+                lifetimes_in_scope,
+            }
+            .decorate_lint(diag);
         }
         BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => {
             lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 8059f5c1a2e..f60f8f7c6b7 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2873,6 +2873,8 @@ pub struct AssociatedConstElidedLifetime {
 
     pub code: &'static str,
     pub elided: bool,
+    #[note]
+    pub lifetimes_in_scope: MultiSpan,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index a12c76037e7..1913b9d6a1c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4593,16 +4593,18 @@ declare_lint! {
 
 declare_lint! {
     /// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes
-    /// that were erroneously allowed in associated constants.
+    /// in associated constants when there are other lifetimes in scope. This was
+    /// accidentally supported, and this lint was later relaxed to allow eliding
+    /// lifetimes to `'static` when there are no lifetimes in scope.
     ///
     /// ### Example
     ///
     /// ```rust,compile_fail
     /// #![deny(elided_lifetimes_in_associated_constant)]
     ///
-    /// struct Foo;
+    /// struct Foo<'a>(&'a ());
     ///
-    /// impl Foo {
+    /// impl<'a> Foo<'a> {
     ///     const STR: &str = "hello, world";
     /// }
     /// ```
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 1ce95df3404..70330c44577 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -696,6 +696,7 @@ pub enum BuiltinLintDiag {
     AssociatedConstElidedLifetime {
         elided: bool,
         span: Span,
+        lifetimes_in_scope: MultiSpan,
     },
     RedundantImportVisibility {
         span: Span,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 1cef35f082b..c9450142cd3 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -191,7 +191,7 @@ impl IntoArgs for (CrateNum, DefId) {
     }
 }
 
-impl<'tcx> IntoArgs for ty::InstanceDef<'tcx> {
+impl<'tcx> IntoArgs for ty::InstanceKind<'tcx> {
     type Other = ();
     fn into_args(self) -> (DefId, ()) {
         (self.def_id(), ())
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index d7840a2d516..4bd2ec09a6e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1693,7 +1693,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses);
             }
 
-            let instance = ty::InstanceDef::Item(def_id.to_def_id());
+            let instance = ty::InstanceKind::Item(def_id.to_def_id());
             let unused = tcx.unused_generic_params(instance);
             self.tables.unused_generic_params.set(def_id.local_def_index, unused);
         }
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index de786c38326..3d4e5caa9b2 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -110,7 +110,7 @@ macro_rules! arena_types {
                     rustc_hir::def_id::DefId,
                     rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
                 >,
-            [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
+            [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
             [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
             [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
             [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs
index 3b6eecb7fa0..b35cc83cb8e 100644
--- a/compiler/rustc_middle/src/middle/exported_symbols.rs
+++ b/compiler/rustc_middle/src/middle/exported_symbols.rs
@@ -64,7 +64,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
                 tcx.symbol_name(ty::Instance::resolve_async_drop_in_place(tcx, ty))
             }
             ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance {
-                def: ty::InstanceDef::ThreadLocalShim(def_id),
+                def: ty::InstanceKind::ThreadLocalShim(def_id),
                 args: ty::GenericArgs::empty(),
             }),
             ExportedSymbol::NoDefId(symbol_name) => symbol_name,
diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs
index 96bef40dac5..2eadc4d553c 100644
--- a/compiler/rustc_middle/src/mir/graphviz.rs
+++ b/compiler/rustc_middle/src/mir/graphviz.rs
@@ -19,7 +19,7 @@ where
             if tcx.is_const_fn_raw(*def_id) {
                 vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
             } else {
-                vec![tcx.instance_mir(ty::InstanceDef::Item(*def_id))]
+                vec![tcx.instance_mir(ty::InstanceKind::Item(*def_id))]
             }
         })
         .collect::<Vec<_>>();
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index eabbcc2033f..23680f14397 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -438,9 +438,6 @@ pub enum ValidationErrorKind<'tcx> {
         ptr_kind: PointerKind,
         ty: Ty<'tcx>,
     },
-    PtrToStatic {
-        ptr_kind: PointerKind,
-    },
     ConstRefToMutable,
     ConstRefToExtern,
     MutableRefToImmutable,
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 02e5174a715..01cefc75194 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -10,7 +10,7 @@ use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{self, List, Ty, TyCtxt};
-use crate::ty::{AdtDef, Instance, InstanceDef, UserTypeAnnotationIndex};
+use crate::ty::{AdtDef, Instance, InstanceKind, UserTypeAnnotationIndex};
 use crate::ty::{GenericArg, GenericArgsRef};
 
 use rustc_data_structures::captures::Captures;
@@ -233,7 +233,7 @@ impl RuntimePhase {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable, TypeVisitable)]
 pub struct MirSource<'tcx> {
-    pub instance: InstanceDef<'tcx>,
+    pub instance: InstanceKind<'tcx>,
 
     /// If `Some`, this is a promoted rvalue within the parent function.
     pub promoted: Option<Promoted>,
@@ -241,10 +241,10 @@ pub struct MirSource<'tcx> {
 
 impl<'tcx> MirSource<'tcx> {
     pub fn item(def_id: DefId) -> Self {
-        MirSource { instance: InstanceDef::Item(def_id), promoted: None }
+        MirSource { instance: InstanceKind::Item(def_id), promoted: None }
     }
 
-    pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
+    pub fn from_instance(instance: InstanceKind<'tcx>) -> Self {
         MirSource { instance, promoted: None }
     }
 
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 3d79ec0092f..146cd6dfbeb 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
-use crate::ty::{GenericArgs, Instance, InstanceDef, SymbolName, TyCtxt};
+use crate::ty::{GenericArgs, Instance, InstanceKind, SymbolName, TyCtxt};
 use rustc_attr::InlineAttr;
 use rustc_data_structures::base_n::BaseNString;
 use rustc_data_structures::base_n::ToBaseN;
@@ -56,7 +56,7 @@ impl<'tcx> MonoItem<'tcx> {
     /// Returns `true` if the mono item is user-defined (i.e. not compiler-generated, like shims).
     pub fn is_user_defined(&self) -> bool {
         match *self {
-            MonoItem::Fn(instance) => matches!(instance.def, InstanceDef::Item(..)),
+            MonoItem::Fn(instance) => matches!(instance.def, InstanceKind::Item(..)),
             MonoItem::Static(..) | MonoItem::GlobalAsm(..) => true,
         }
     }
@@ -69,9 +69,9 @@ impl<'tcx> MonoItem<'tcx> {
                 match instance.def {
                     // "Normal" functions size estimate: the number of
                     // statements, plus one for the terminator.
-                    InstanceDef::Item(..)
-                    | InstanceDef::DropGlue(..)
-                    | InstanceDef::AsyncDropGlueCtorShim(..) => {
+                    InstanceKind::Item(..)
+                    | InstanceKind::DropGlue(..)
+                    | InstanceKind::AsyncDropGlueCtorShim(..) => {
                         let mir = tcx.instance_mir(instance.def);
                         mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum()
                     }
@@ -407,20 +407,20 @@ impl<'tcx> CodegenUnit<'tcx> {
                             // instances into account. The others don't matter for
                             // the codegen tests and can even make item order
                             // unstable.
-                            InstanceDef::Item(def) => def.as_local().map(Idx::index),
-                            InstanceDef::VTableShim(..)
-                            | InstanceDef::ReifyShim(..)
-                            | InstanceDef::Intrinsic(..)
-                            | InstanceDef::FnPtrShim(..)
-                            | InstanceDef::Virtual(..)
-                            | InstanceDef::ClosureOnceShim { .. }
-                            | InstanceDef::ConstructCoroutineInClosureShim { .. }
-                            | InstanceDef::CoroutineKindShim { .. }
-                            | InstanceDef::DropGlue(..)
-                            | InstanceDef::CloneShim(..)
-                            | InstanceDef::ThreadLocalShim(..)
-                            | InstanceDef::FnPtrAddrShim(..)
-                            | InstanceDef::AsyncDropGlueCtorShim(..) => None,
+                            InstanceKind::Item(def) => def.as_local().map(Idx::index),
+                            InstanceKind::VTableShim(..)
+                            | InstanceKind::ReifyShim(..)
+                            | InstanceKind::Intrinsic(..)
+                            | InstanceKind::FnPtrShim(..)
+                            | InstanceKind::Virtual(..)
+                            | InstanceKind::ClosureOnceShim { .. }
+                            | InstanceKind::ConstructCoroutineInClosureShim { .. }
+                            | InstanceKind::CoroutineKindShim { .. }
+                            | InstanceKind::DropGlue(..)
+                            | InstanceKind::CloneShim(..)
+                            | InstanceKind::ThreadLocalShim(..)
+                            | InstanceKind::FnPtrAddrShim(..)
+                            | InstanceKind::AsyncDropGlueCtorShim(..) => None,
                         }
                     }
                     MonoItem::Static(def_id) => def_id.as_local().map(Idx::index),
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index f1c3cb69896..4657f4dcf81 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -177,7 +177,7 @@ fn dump_path<'tcx>(
     // All drop shims have the same DefId, so we have to add the type
     // to get unique file names.
     let shim_disambiguator = match source.instance {
-        ty::InstanceDef::DropGlue(_, Some(ty)) => {
+        ty::InstanceKind::DropGlue(_, Some(ty)) => {
             // Unfortunately, pretty-printed typed are not very filename-friendly.
             // We dome some filtering.
             let mut s = ".".to_owned();
@@ -188,7 +188,7 @@ fn dump_path<'tcx>(
             }));
             s
         }
-        ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => {
+        ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) => {
             // Unfortunately, pretty-printed typed are not very filename-friendly.
             // We dome some filtering.
             let mut s = ".".to_owned();
@@ -280,7 +280,7 @@ pub fn write_mir_pretty<'tcx>(
             // are shared between mir_for_ctfe and optimized_mir
             write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?;
         } else {
-            let instance_mir = tcx.instance_mir(ty::InstanceDef::Item(def_id));
+            let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
             render_body(w, instance_mir)?;
         }
     }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 10609e56f2c..7628a1ed2fe 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -337,27 +337,27 @@ macro_rules! make_mir_visitor {
 
                     let ty::Instance { def: callee_def, args: callee_args } = callee;
                     match callee_def {
-                        ty::InstanceDef::Item(_def_id) => {}
-
-                        ty::InstanceDef::Intrinsic(_def_id) |
-                        ty::InstanceDef::VTableShim(_def_id) |
-                        ty::InstanceDef::ReifyShim(_def_id, _) |
-                        ty::InstanceDef::Virtual(_def_id, _) |
-                        ty::InstanceDef::ThreadLocalShim(_def_id) |
-                        ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
-                        ty::InstanceDef::ConstructCoroutineInClosureShim {
+                        ty::InstanceKind::Item(_def_id) => {}
+
+                        ty::InstanceKind::Intrinsic(_def_id) |
+                        ty::InstanceKind::VTableShim(_def_id) |
+                        ty::InstanceKind::ReifyShim(_def_id, _) |
+                        ty::InstanceKind::Virtual(_def_id, _) |
+                        ty::InstanceKind::ThreadLocalShim(_def_id) |
+                        ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
+                        ty::InstanceKind::ConstructCoroutineInClosureShim {
                             coroutine_closure_def_id: _def_id,
                             receiver_by_ref: _,
                         } |
-                        ty::InstanceDef::CoroutineKindShim { coroutine_def_id: _def_id } |
-                        ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, None) |
-                        ty::InstanceDef::DropGlue(_def_id, None) => {}
-
-                        ty::InstanceDef::FnPtrShim(_def_id, ty) |
-                        ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
-                        ty::InstanceDef::CloneShim(_def_id, ty) |
-                        ty::InstanceDef::FnPtrAddrShim(_def_id, ty) |
-                        ty::InstanceDef::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
+                        ty::InstanceKind::CoroutineKindShim { coroutine_def_id: _def_id } |
+                        ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) |
+                        ty::InstanceKind::DropGlue(_def_id, None) => {}
+
+                        ty::InstanceKind::FnPtrShim(_def_id, ty) |
+                        ty::InstanceKind::DropGlue(_def_id, Some(ty)) |
+                        ty::InstanceKind::CloneShim(_def_id, ty) |
+                        ty::InstanceKind::FnPtrAddrShim(_def_id, ty) |
+                        ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
                             // FIXME(eddyb) use a better `TyContext` here.
                             self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
                         }
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index b29a86d58ed..301c9911b44 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -365,7 +365,7 @@ tcx_lifetime! {
     rustc_middle::ty::GenericPredicates,
     rustc_middle::ty::inhabitedness::InhabitedPredicate,
     rustc_middle::ty::Instance,
-    rustc_middle::ty::InstanceDef,
+    rustc_middle::ty::InstanceKind,
     rustc_middle::ty::layout::FnAbiError,
     rustc_middle::ty::layout::LayoutError,
     rustc_middle::ty::ParamEnv,
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 5452e1dff3e..add88491f84 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -62,7 +62,7 @@ impl Key for () {
     }
 }
 
-impl<'tcx> Key for ty::InstanceDef<'tcx> {
+impl<'tcx> Key for ty::InstanceKind<'tcx> {
     type Cache<V> = DefaultCache<Self, V>;
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
@@ -70,7 +70,7 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {
     }
 }
 
-impl<'tcx> AsLocalKey for ty::InstanceDef<'tcx> {
+impl<'tcx> AsLocalKey for ty::InstanceKind<'tcx> {
     type LocalKey = Self;
 
     #[inline(always)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 8ba930f493e..0f08694c4ea 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -575,7 +575,7 @@ rustc_queries! {
     /// Summarizes coverage IDs inserted by the `InstrumentCoverage` MIR pass
     /// (for compiler option `-Cinstrument-coverage`), after MIR optimizations
     /// have had a chance to potentially remove some of them.
-    query coverage_ids_info(key: ty::InstanceDef<'tcx>) -> &'tcx mir::CoverageIdsInfo {
+    query coverage_ids_info(key: ty::InstanceKind<'tcx>) -> &'tcx mir::CoverageIdsInfo {
         desc { |tcx| "retrieving coverage IDs info from MIR for `{}`", tcx.def_path_str(key.def_id()) }
         arena_cache
     }
@@ -1033,7 +1033,7 @@ rustc_queries! {
     }
 
     /// Obtain all the calls into other local functions
-    query mir_inliner_callees(key: ty::InstanceDef<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] {
+    query mir_inliner_callees(key: ty::InstanceKind<'tcx>) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] {
         fatal_cycle
         desc { |tcx|
             "computing all local function calls in `{}`",
@@ -1140,7 +1140,7 @@ rustc_queries! {
     }
 
     /// Generates a MIR body for the shim.
-    query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::Body<'tcx> {
+    query mir_shims(key: ty::InstanceKind<'tcx>) -> &'tcx mir::Body<'tcx> {
         arena_cache
         desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) }
     }
@@ -1410,7 +1410,7 @@ rustc_queries! {
     /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
     ///
     /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
-    /// instead, where the instance is an `InstanceDef::Virtual`.
+    /// instead, where the instance is an `InstanceKind::Virtual`.
     query fn_abi_of_fn_ptr(
         key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
@@ -1421,7 +1421,7 @@ rustc_queries! {
     /// direct calls to an `fn`.
     ///
     /// NB: that includes virtual calls, which are represented by "direct calls"
-    /// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
+    /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
     query fn_abi_of_instance(
         key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>
     ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, &'tcx ty::layout::FnAbiError<'tcx>> {
@@ -1918,7 +1918,7 @@ rustc_queries! {
         desc { "getting codegen unit `{sym}`" }
     }
 
-    query unused_generic_params(key: ty::InstanceDef<'tcx>) -> UnusedGenericParams {
+    query unused_generic_params(key: ty::InstanceKind<'tcx>) -> UnusedGenericParams {
         cache_on_disk_if { key.def_id().is_local() }
         desc {
             |tcx| "determining which generic parameters are unused by `{}`",
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 202d587f0ad..b4e3fae1b43 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -32,54 +32,7 @@ use std::hash::{Hash, Hasher};
 
 pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
 // FIXME: Remove this import and import via `solve::`
-pub use rustc_type_ir::solve::BuiltinImplSource;
-
-/// Depending on the stage of compilation, we want projection to be
-/// more or less conservative.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)]
-pub enum Reveal {
-    /// At type-checking time, we refuse to project any associated
-    /// type that is marked `default`. Non-`default` ("final") types
-    /// are always projected. This is necessary in general for
-    /// soundness of specialization. However, we *could* allow
-    /// projections in fully-monomorphic cases. We choose not to,
-    /// because we prefer for `default type` to force the type
-    /// definition to be treated abstractly by any consumers of the
-    /// impl. Concretely, that means that the following example will
-    /// fail to compile:
-    ///
-    /// ```compile_fail,E0308
-    /// #![feature(specialization)]
-    /// trait Assoc {
-    ///     type Output;
-    /// }
-    ///
-    /// impl<T> Assoc for T {
-    ///     default type Output = bool;
-    /// }
-    ///
-    /// fn main() {
-    ///     let x: <() as Assoc>::Output = true;
-    /// }
-    /// ```
-    ///
-    /// We also do not reveal the hidden type of opaque types during
-    /// type-checking.
-    UserFacing,
-
-    /// At codegen time, all monomorphic projections will succeed.
-    /// Also, `impl Trait` is normalized to the concrete type,
-    /// which has to be already collected by type-checking.
-    ///
-    /// NOTE: as `impl Trait`'s concrete type should *never*
-    /// be observable directly by the user, `Reveal::All`
-    /// should not be used by checks which may expose
-    /// type equality or type contents to the user.
-    /// There are some exceptions, e.g., around auto traits and
-    /// transmute-checking, which expose some details, but
-    /// not the whole concrete type of the `impl Trait`.
-    All,
-}
+pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal};
 
 /// The reason why we incurred this obligation; used for error reporting.
 ///
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 0d9ce402c64..9e979620a44 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -1,10 +1,9 @@
 use rustc_ast_ir::try_visit;
 use rustc_data_structures::intern::Interned;
-use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
+use rustc_macros::HashStable;
 use rustc_type_ir as ir;
 pub use rustc_type_ir::solve::*;
 
-use crate::infer::canonical::QueryRegionConstraints;
 use crate::ty::{
     self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
 };
@@ -38,37 +37,18 @@ impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
 }
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
-pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
+pub struct ExternalConstraints<'tcx>(
+    pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
+);
 
 impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
-    type Target = ExternalConstraintsData<'tcx>;
+    type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
 
     fn deref(&self) -> &Self::Target {
         &self.0
     }
 }
 
-/// Additional constraints returned on success.
-#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
-pub struct ExternalConstraintsData<'tcx> {
-    // FIXME: implement this.
-    pub region_constraints: QueryRegionConstraints<'tcx>,
-    pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
-    pub normalization_nested_goals: NestedNormalizationGoals<'tcx>,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
-pub struct NestedNormalizationGoals<'tcx>(pub Vec<(GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>);
-impl<'tcx> NestedNormalizationGoals<'tcx> {
-    pub fn empty() -> Self {
-        NestedNormalizationGoals(vec![])
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.0.is_empty()
-    }
-}
-
 // FIXME: Having to clone `region_constraints` for folding feels bad and
 // probably isn't great wrt performance.
 //
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 3651c990c97..e2f15dac019 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -88,6 +88,7 @@ use std::ops::{Bound, Deref};
 #[allow(rustc::usage_of_ty_tykind)]
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type DefId = DefId;
+    type LocalDefId = LocalDefId;
     type AdtDef = ty::AdtDef<'tcx>;
 
     type GenericArgs = ty::GenericArgsRef<'tcx>;
@@ -382,7 +383,7 @@ pub struct CtxtInterners<'tcx> {
     bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
     layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>,
     adt_def: InternedSet<'tcx, AdtDefData>,
-    external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
+    external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
     predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
     fields: InternedSet<'tcx, List<FieldIdx>>,
     local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
@@ -2093,7 +2094,7 @@ direct_interners! {
     const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
     layout: pub mk_layout(LayoutS<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
     adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
-    external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>):
+    external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
         ExternalConstraints -> ExternalConstraints<'tcx>,
     predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>):
         PredefinedOpaques -> PredefinedOpaques<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index bdf90cbb25b..5718264c944 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -19,10 +19,10 @@ use tracing::{debug, instrument};
 use std::assert_matches::assert_matches;
 use std::fmt;
 
-/// A monomorphized `InstanceDef`.
+/// An `InstanceKind` along with the args that are needed to substitute the instance.
 ///
 /// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
-/// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval
+/// simply couples a potentially generic `InstanceKind` with some args, and codegen and const eval
 /// will do all required instantiations as they run.
 ///
 /// Note: the `Lift` impl is currently not used by rustc, but is used by
@@ -30,7 +30,7 @@ use std::fmt;
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
 pub struct Instance<'tcx> {
-    pub def: InstanceDef<'tcx>,
+    pub def: InstanceKind<'tcx>,
     pub args: GenericArgsRef<'tcx>,
 }
 
@@ -58,7 +58,7 @@ pub enum ReifyReason {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
-pub enum InstanceDef<'tcx> {
+pub enum InstanceKind<'tcx> {
     /// A user-defined callable item.
     ///
     /// This includes:
@@ -69,7 +69,7 @@ pub enum InstanceDef<'tcx> {
 
     /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
     ///
-    /// Alongside `Virtual`, this is the only `InstanceDef` that does not have its own callable MIR.
+    /// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
     /// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
     /// caller.
     Intrinsic(DefId),
@@ -85,7 +85,7 @@ pub enum InstanceDef<'tcx> {
     ///
     /// One example is `<dyn Trait as Trait>::fn`, where the shim contains
     /// a virtual call, which codegen supports only via a direct call to the
-    /// `<dyn Trait as Trait>::fn` instance (an `InstanceDef::Virtual`).
+    /// `<dyn Trait as Trait>::fn` instance (an `InstanceKind::Virtual`).
     ///
     /// Another example is functions annotated with `#[track_caller]`, which
     /// must have their implicit caller location argument populated for a call.
@@ -107,7 +107,7 @@ pub enum InstanceDef<'tcx> {
 
     /// Dynamic dispatch to `<dyn Trait as Trait>::fn`.
     ///
-    /// This `InstanceDef` does not have callable MIR. Calls to `Virtual` instances must be
+    /// This `InstanceKind` does not have callable MIR. Calls to `Virtual` instances must be
     /// codegen'd as virtual calls through the vtable.
     ///
     /// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more
@@ -216,10 +216,10 @@ impl<'tcx> Instance<'tcx> {
         }
 
         match self.def {
-            InstanceDef::Item(def) => tcx
+            InstanceKind::Item(def) => tcx
                 .upstream_monomorphizations_for(def)
                 .and_then(|monos| monos.get(&self.args).cloned()),
-            InstanceDef::DropGlue(_, Some(_)) | InstanceDef::AsyncDropGlueCtorShim(_, _) => {
+            InstanceKind::DropGlue(_, Some(_)) | InstanceKind::AsyncDropGlueCtorShim(_, _) => {
                 tcx.upstream_drop_glue_for(self.args)
             }
             _ => None,
@@ -227,48 +227,48 @@ impl<'tcx> Instance<'tcx> {
     }
 }
 
-impl<'tcx> InstanceDef<'tcx> {
+impl<'tcx> InstanceKind<'tcx> {
     #[inline]
     pub fn def_id(self) -> DefId {
         match self {
-            InstanceDef::Item(def_id)
-            | InstanceDef::VTableShim(def_id)
-            | InstanceDef::ReifyShim(def_id, _)
-            | InstanceDef::FnPtrShim(def_id, _)
-            | InstanceDef::Virtual(def_id, _)
-            | InstanceDef::Intrinsic(def_id)
-            | InstanceDef::ThreadLocalShim(def_id)
-            | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
-            | ty::InstanceDef::ConstructCoroutineInClosureShim {
+            InstanceKind::Item(def_id)
+            | InstanceKind::VTableShim(def_id)
+            | InstanceKind::ReifyShim(def_id, _)
+            | InstanceKind::FnPtrShim(def_id, _)
+            | InstanceKind::Virtual(def_id, _)
+            | InstanceKind::Intrinsic(def_id)
+            | InstanceKind::ThreadLocalShim(def_id)
+            | InstanceKind::ClosureOnceShim { call_once: def_id, track_caller: _ }
+            | ty::InstanceKind::ConstructCoroutineInClosureShim {
                 coroutine_closure_def_id: def_id,
                 receiver_by_ref: _,
             }
-            | ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id }
-            | InstanceDef::DropGlue(def_id, _)
-            | InstanceDef::CloneShim(def_id, _)
-            | InstanceDef::FnPtrAddrShim(def_id, _)
-            | InstanceDef::AsyncDropGlueCtorShim(def_id, _) => def_id,
+            | ty::InstanceKind::CoroutineKindShim { coroutine_def_id: def_id }
+            | InstanceKind::DropGlue(def_id, _)
+            | InstanceKind::CloneShim(def_id, _)
+            | InstanceKind::FnPtrAddrShim(def_id, _)
+            | InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id,
         }
     }
 
     /// Returns the `DefId` of instances which might not require codegen locally.
     pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
         match self {
-            ty::InstanceDef::Item(def) => Some(def),
-            ty::InstanceDef::DropGlue(def_id, Some(_))
-            | InstanceDef::AsyncDropGlueCtorShim(def_id, _)
-            | InstanceDef::ThreadLocalShim(def_id) => Some(def_id),
-            InstanceDef::VTableShim(..)
-            | InstanceDef::ReifyShim(..)
-            | InstanceDef::FnPtrShim(..)
-            | InstanceDef::Virtual(..)
-            | InstanceDef::Intrinsic(..)
-            | InstanceDef::ClosureOnceShim { .. }
-            | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceDef::CoroutineKindShim { .. }
-            | InstanceDef::DropGlue(..)
-            | InstanceDef::CloneShim(..)
-            | InstanceDef::FnPtrAddrShim(..) => None,
+            ty::InstanceKind::Item(def) => Some(def),
+            ty::InstanceKind::DropGlue(def_id, Some(_))
+            | InstanceKind::AsyncDropGlueCtorShim(def_id, _)
+            | InstanceKind::ThreadLocalShim(def_id) => Some(def_id),
+            InstanceKind::VTableShim(..)
+            | InstanceKind::ReifyShim(..)
+            | InstanceKind::FnPtrShim(..)
+            | InstanceKind::Virtual(..)
+            | InstanceKind::Intrinsic(..)
+            | InstanceKind::ClosureOnceShim { .. }
+            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | ty::InstanceKind::CoroutineKindShim { .. }
+            | InstanceKind::DropGlue(..)
+            | InstanceKind::CloneShim(..)
+            | InstanceKind::FnPtrAddrShim(..) => None,
         }
     }
 
@@ -289,10 +289,10 @@ impl<'tcx> InstanceDef<'tcx> {
     pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
         use rustc_hir::definitions::DefPathData;
         let def_id = match *self {
-            ty::InstanceDef::Item(def) => def,
-            ty::InstanceDef::DropGlue(_, Some(_)) => return false,
-            ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => return false,
-            ty::InstanceDef::ThreadLocalShim(_) => return false,
+            ty::InstanceKind::Item(def) => def,
+            ty::InstanceKind::DropGlue(_, Some(_)) => return false,
+            ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => return false,
+            ty::InstanceKind::ThreadLocalShim(_) => return false,
             _ => return true,
         };
         matches!(
@@ -312,7 +312,7 @@ impl<'tcx> InstanceDef<'tcx> {
         if self.requires_inline(tcx) {
             return true;
         }
-        if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
+        if let ty::InstanceKind::DropGlue(.., Some(ty)) = *self {
             // Drop glue generally wants to be instantiated at every codegen
             // unit, but without an #[inline] hint. We should make this
             // available to normal end-users.
@@ -332,7 +332,7 @@ impl<'tcx> InstanceDef<'tcx> {
                     .map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did))
             });
         }
-        if let ty::InstanceDef::ThreadLocalShim(..) = *self {
+        if let ty::InstanceKind::ThreadLocalShim(..) = *self {
             return false;
         }
         tcx.cross_crate_inlinable(self.def_id())
@@ -340,10 +340,10 @@ impl<'tcx> InstanceDef<'tcx> {
 
     pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
         match *self {
-            InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => {
+            InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) => {
                 tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
             }
-            InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
+            InstanceKind::ClosureOnceShim { call_once: _, track_caller } => track_caller,
             _ => false,
         }
     }
@@ -356,22 +356,22 @@ impl<'tcx> InstanceDef<'tcx> {
     /// body should perform necessary instantiations.
     pub fn has_polymorphic_mir_body(&self) -> bool {
         match *self {
-            InstanceDef::CloneShim(..)
-            | InstanceDef::ThreadLocalShim(..)
-            | InstanceDef::FnPtrAddrShim(..)
-            | InstanceDef::FnPtrShim(..)
-            | InstanceDef::DropGlue(_, Some(_))
-            | InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false,
-            InstanceDef::ClosureOnceShim { .. }
-            | InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | InstanceDef::CoroutineKindShim { .. }
-            | InstanceDef::DropGlue(..)
-            | InstanceDef::AsyncDropGlueCtorShim(..)
-            | InstanceDef::Item(_)
-            | InstanceDef::Intrinsic(..)
-            | InstanceDef::ReifyShim(..)
-            | InstanceDef::Virtual(..)
-            | InstanceDef::VTableShim(..) => true,
+            InstanceKind::CloneShim(..)
+            | InstanceKind::ThreadLocalShim(..)
+            | InstanceKind::FnPtrAddrShim(..)
+            | InstanceKind::FnPtrShim(..)
+            | InstanceKind::DropGlue(_, Some(_))
+            | InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false,
+            InstanceKind::ClosureOnceShim { .. }
+            | InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | InstanceKind::CoroutineKindShim { .. }
+            | InstanceKind::DropGlue(..)
+            | InstanceKind::AsyncDropGlueCtorShim(..)
+            | InstanceKind::Item(_)
+            | InstanceKind::Intrinsic(..)
+            | InstanceKind::ReifyShim(..)
+            | InstanceKind::Virtual(..)
+            | InstanceKind::VTableShim(..) => true,
         }
     }
 }
@@ -395,24 +395,24 @@ fn fmt_instance(
     })?;
 
     match instance.def {
-        InstanceDef::Item(_) => Ok(()),
-        InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
-        InstanceDef::ReifyShim(_, None) => write!(f, " - shim(reify)"),
-        InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => write!(f, " - shim(reify-fnptr)"),
-        InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => write!(f, " - shim(reify-vtable)"),
-        InstanceDef::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
-        InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
-        InstanceDef::Virtual(_, num) => write!(f, " - virtual#{num}"),
-        InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({ty})"),
-        InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
-        InstanceDef::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"),
-        InstanceDef::CoroutineKindShim { .. } => write!(f, " - shim"),
-        InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
-        InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
-        InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"),
-        InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
-        InstanceDef::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
-        InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
+        InstanceKind::Item(_) => Ok(()),
+        InstanceKind::VTableShim(_) => write!(f, " - shim(vtable)"),
+        InstanceKind::ReifyShim(_, None) => write!(f, " - shim(reify)"),
+        InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => write!(f, " - shim(reify-fnptr)"),
+        InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => write!(f, " - shim(reify-vtable)"),
+        InstanceKind::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
+        InstanceKind::Intrinsic(_) => write!(f, " - intrinsic"),
+        InstanceKind::Virtual(_, num) => write!(f, " - virtual#{num}"),
+        InstanceKind::FnPtrShim(_, ty) => write!(f, " - shim({ty})"),
+        InstanceKind::ClosureOnceShim { .. } => write!(f, " - shim"),
+        InstanceKind::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"),
+        InstanceKind::CoroutineKindShim { .. } => write!(f, " - shim"),
+        InstanceKind::DropGlue(_, None) => write!(f, " - shim(None)"),
+        InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
+        InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"),
+        InstanceKind::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
+        InstanceKind::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
+        InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
     }
 }
 
@@ -434,9 +434,9 @@ impl<'tcx> Instance<'tcx> {
     pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
         assert!(
             !args.has_escaping_bound_vars(),
-            "args of instance {def_id:?} not normalized for codegen: {args:?}"
+            "args of instance {def_id:?} has escaping bound vars: {args:?}"
         );
-        Instance { def: InstanceDef::Item(def_id), args }
+        Instance { def: InstanceKind::Item(def_id), args }
     }
 
     pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
@@ -526,13 +526,13 @@ impl<'tcx> Instance<'tcx> {
         let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr);
         Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
             match resolved.def {
-                InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
+                InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => {
                     debug!(" => fn pointer created for function with #[track_caller]");
-                    resolved.def = InstanceDef::ReifyShim(def, reason);
+                    resolved.def = InstanceKind::ReifyShim(def, reason);
                 }
-                InstanceDef::Virtual(def_id, _) => {
+                InstanceKind::Virtual(def_id, _) => {
                     debug!(" => fn pointer created for virtual call");
-                    resolved.def = InstanceDef::ReifyShim(def_id, reason);
+                    resolved.def = InstanceKind::ReifyShim(def_id, reason);
                 }
                 // Reify `Trait::method` implementations if KCFI is enabled
                 // FIXME(maurer) only reify it if it is a vtable-safe function
@@ -544,7 +544,7 @@ impl<'tcx> Instance<'tcx> {
                 {
                     // If this function could also go in a vtable, we need to `ReifyShim` it with
                     // KCFI because it can only attach one type per function.
-                    resolved.def = InstanceDef::ReifyShim(resolved.def_id(), reason)
+                    resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
                 }
                 // Reify `::call`-like method implementations if KCFI is enabled
                 _ if tcx.sess.is_sanitizer_kcfi_enabled()
@@ -553,7 +553,7 @@ impl<'tcx> Instance<'tcx> {
                     // Reroute through a reify via the *unresolved* instance. The resolved one can't
                     // be directly reified because it's closure-like. The reify can handle the
                     // unresolved instance.
-                    resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args }
+                    resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
                 }
                 _ => {}
             }
@@ -575,12 +575,12 @@ impl<'tcx> Instance<'tcx> {
             && tcx.generics_of(def_id).has_self;
         if is_vtable_shim {
             debug!(" => associated item with unsizeable self: Self");
-            Some(Instance { def: InstanceDef::VTableShim(def_id), args })
+            Some(Instance { def: InstanceKind::VTableShim(def_id), args })
         } else {
             let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable);
             Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
                 match resolved.def {
-                    InstanceDef::Item(def) => {
+                    InstanceKind::Item(def) => {
                         // We need to generate a shim when we cannot guarantee that
                         // the caller of a trait object method will be aware of
                         // `#[track_caller]` - this ensures that the caller
@@ -614,18 +614,18 @@ impl<'tcx> Instance<'tcx> {
                                 // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
                                 // - unlike functions, invoking a closure always goes through a
                                 // trait.
-                                resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args };
+                                resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args };
                             } else {
                                 debug!(
                                     " => vtable fn pointer created for function with #[track_caller]: {:?}", def
                                 );
-                                resolved.def = InstanceDef::ReifyShim(def, reason);
+                                resolved.def = InstanceKind::ReifyShim(def, reason);
                             }
                         }
                     }
-                    InstanceDef::Virtual(def_id, _) => {
+                    InstanceKind::Virtual(def_id, _) => {
                         debug!(" => vtable fn pointer created for virtual call");
-                        resolved.def = InstanceDef::ReifyShim(def_id, reason)
+                        resolved.def = InstanceKind::ReifyShim(def_id, reason)
                     }
                     _ => {}
                 }
@@ -676,7 +676,7 @@ impl<'tcx> Instance<'tcx> {
             .def_id;
         let track_caller =
             tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER);
-        let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller };
+        let def = ty::InstanceKind::ClosureOnceShim { call_once, track_caller };
 
         let self_ty = Ty::new_closure(tcx, closure_did, args);
 
@@ -733,10 +733,10 @@ impl<'tcx> Instance<'tcx> {
             // If the closure's kind ty disagrees with the identity closure's kind ty,
             // then this must be a coroutine generated by one of the `ConstructCoroutineInClosureShim`s.
             if args.as_coroutine().kind_ty() == id_args.as_coroutine().kind_ty() {
-                Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
+                Some(Instance { def: ty::InstanceKind::Item(coroutine_def_id), args })
             } else {
                 Some(Instance {
-                    def: ty::InstanceDef::CoroutineKindShim { coroutine_def_id },
+                    def: ty::InstanceKind::CoroutineKindShim { coroutine_def_id },
                     args,
                 })
             }
@@ -749,7 +749,7 @@ impl<'tcx> Instance<'tcx> {
         }
     }
 
-    /// Depending on the kind of `InstanceDef`, the MIR body associated with an
+    /// Depending on the kind of `InstanceKind`, the MIR body associated with an
     /// instance is expressed in terms of the generic parameters of `self.def_id()`, and in other
     /// cases the MIR body is expressed in terms of the types found in the generic parameter array.
     /// In the former case, we want to instantiate those generic types and replace them with the
@@ -832,7 +832,7 @@ impl<'tcx> Instance<'tcx> {
 
 fn polymorphize<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: ty::InstanceDef<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
     args: GenericArgsRef<'tcx>,
 ) -> GenericArgsRef<'tcx> {
     debug!("polymorphize({:?}, {:?})", instance, args);
@@ -873,7 +873,7 @@ fn polymorphize<'tcx>(
             match *ty.kind() {
                 ty::Closure(def_id, args) => {
                     let polymorphized_args =
-                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
+                        polymorphize(self.tcx, ty::InstanceKind::Item(def_id), args);
                     if args == polymorphized_args {
                         ty
                     } else {
@@ -882,7 +882,7 @@ fn polymorphize<'tcx>(
                 }
                 ty::Coroutine(def_id, args) => {
                     let polymorphized_args =
-                        polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
+                        polymorphize(self.tcx, ty::InstanceKind::Item(def_id), args);
                     if args == polymorphized_args {
                         ty
                     } else {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 02c0d41f619..cf7610bb4f6 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1302,7 +1302,7 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
     /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
     ///
     /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance`
-    /// instead, where the instance is an `InstanceDef::Virtual`.
+    /// instead, where the instance is an `InstanceKind::Virtual`.
     #[inline]
     fn fn_abi_of_fn_ptr(
         &self,
@@ -1322,7 +1322,7 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> {
     /// direct calls to an `fn`.
     ///
     /// NB: that includes virtual calls, which are represented by "direct calls"
-    /// to an `InstanceDef::Virtual` instance (of `<dyn Trait as Trait>::fn`).
+    /// to an `InstanceKind::Virtual` instance (of `<dyn Trait as Trait>::fn`).
     #[inline]
     #[tracing::instrument(level = "debug", skip(self))]
     fn fn_abi_of_instance(
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 5a94a53e175..d07541bad93 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -92,8 +92,9 @@ pub use self::context::{
     tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift,
     TyCtxt, TyCtxtFeed,
 };
-pub use self::instance::{Instance, InstanceDef, ReifyReason, ShortInstance, UnusedGenericParams};
+pub use self::instance::{Instance, InstanceKind, ReifyReason, ShortInstance, UnusedGenericParams};
 pub use self::list::{List, ListWithCachedTypeInfo};
+pub use self::opaque_types::OpaqueTypeKey;
 pub use self::parameterized::ParameterizedOverTcx;
 pub use self::pattern::{Pattern, PatternKind};
 pub use self::predicate::{
@@ -758,45 +759,6 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct OpaqueTypeKey<'tcx> {
-    pub def_id: LocalDefId,
-    pub args: GenericArgsRef<'tcx>,
-}
-
-impl<'tcx> OpaqueTypeKey<'tcx> {
-    pub fn iter_captured_args(
-        self,
-        tcx: TyCtxt<'tcx>,
-    ) -> impl Iterator<Item = (usize, GenericArg<'tcx>)> {
-        std::iter::zip(self.args, tcx.variances_of(self.def_id)).enumerate().filter_map(
-            |(i, (arg, v))| match (arg.unpack(), v) {
-                (_, ty::Invariant) => Some((i, arg)),
-                (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
-                _ => bug!("unexpected opaque type arg variance"),
-            },
-        )
-    }
-
-    pub fn fold_captured_lifetime_args(
-        self,
-        tcx: TyCtxt<'tcx>,
-        mut f: impl FnMut(Region<'tcx>) -> Region<'tcx>,
-    ) -> Self {
-        let Self { def_id, args } = self;
-        let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
-            match (arg.unpack(), v) {
-                (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
-                (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
-                _ => arg,
-            }
-        });
-        let args = tcx.mk_args_from_iter(args);
-        Self { def_id, args }
-    }
-}
-
 #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
 pub struct OpaqueHiddenType<'tcx> {
     /// The span of this particular definition of the opaque type. So
@@ -1731,11 +1693,11 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    /// Returns the possibly-auto-generated MIR of a [`ty::InstanceDef`].
+    /// Returns the possibly-auto-generated MIR of a [`ty::InstanceKind`].
     #[instrument(skip(self), level = "debug")]
-    pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
+    pub fn instance_mir(self, instance: ty::InstanceKind<'tcx>) -> &'tcx Body<'tcx> {
         match instance {
-            ty::InstanceDef::Item(def) => {
+            ty::InstanceKind::Item(def) => {
                 debug!("calling def_kind on def: {:?}", def);
                 let def_kind = self.def_kind(def);
                 debug!("returned from def_kind: {:?}", def_kind);
@@ -1751,19 +1713,19 @@ impl<'tcx> TyCtxt<'tcx> {
                     _ => self.optimized_mir(def),
                 }
             }
-            ty::InstanceDef::VTableShim(..)
-            | ty::InstanceDef::ReifyShim(..)
-            | ty::InstanceDef::Intrinsic(..)
-            | ty::InstanceDef::FnPtrShim(..)
-            | ty::InstanceDef::Virtual(..)
-            | ty::InstanceDef::ClosureOnceShim { .. }
-            | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceDef::CoroutineKindShim { .. }
-            | ty::InstanceDef::DropGlue(..)
-            | ty::InstanceDef::CloneShim(..)
-            | ty::InstanceDef::ThreadLocalShim(..)
-            | ty::InstanceDef::FnPtrAddrShim(..)
-            | ty::InstanceDef::AsyncDropGlueCtorShim(..) => self.mir_shims(instance),
+            ty::InstanceKind::VTableShim(..)
+            | ty::InstanceKind::ReifyShim(..)
+            | ty::InstanceKind::Intrinsic(..)
+            | ty::InstanceKind::FnPtrShim(..)
+            | ty::InstanceKind::Virtual(..)
+            | ty::InstanceKind::ClosureOnceShim { .. }
+            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | ty::InstanceKind::CoroutineKindShim { .. }
+            | ty::InstanceKind::DropGlue(..)
+            | ty::InstanceKind::CloneShim(..)
+            | ty::InstanceKind::ThreadLocalShim(..)
+            | ty::InstanceKind::FnPtrAddrShim(..)
+            | ty::InstanceKind::AsyncDropGlueCtorShim(..) => self.mir_shims(instance),
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 52902aadd7c..08b2f9e8920 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -7,6 +7,8 @@ use rustc_span::def_id::DefId;
 use rustc_span::Span;
 use tracing::{debug, instrument, trace};
 
+pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey<TyCtxt<'tcx>>;
+
 /// Converts generic params of a TypeFoldable from one
 /// item's generics to another. Usually from a function's generics
 /// list to the opaque type's own generics.
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 84512e81637..bf79b4e133a 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -68,7 +68,7 @@ use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::CoroutineArgs;
-use rustc_middle::ty::InstanceDef;
+use rustc_middle::ty::InstanceKind;
 use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
@@ -1276,7 +1276,7 @@ fn create_coroutine_drop_shim<'tcx>(
     // Update the body's def to become the drop glue.
     let coroutine_instance = body.source.instance;
     let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
-    let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty));
+    let drop_instance = InstanceKind::DropGlue(drop_in_place, Some(coroutine_ty));
 
     // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
     // filename.
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 10c0567eb4b..69d21a63f55 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -75,7 +75,7 @@ use rustc_middle::bug;
 use rustc_middle::hir::place::{Projection, ProjectionKind};
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::{self, dump_mir, MirPass};
-use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
 use rustc_target::abi::{FieldIdx, VariantIdx};
 
 pub struct ByMoveBody;
@@ -102,7 +102,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
 
         // We don't need to generate a by-move coroutine if the coroutine body was
         // produced by the `CoroutineKindShim`, since it's already by-move.
-        if matches!(body.source.instance, ty::InstanceDef::CoroutineKindShim { .. }) {
+        if matches!(body.source.instance, ty::InstanceKind::CoroutineKindShim { .. }) {
             return;
         }
 
@@ -193,7 +193,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
         MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
         dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(()));
         // FIXME: use query feeding to generate the body right here and then only store the `DefId` of the new body.
-        by_move_body.source = mir::MirSource::from_instance(InstanceDef::CoroutineKindShim {
+        by_move_body.source = mir::MirSource::from_instance(InstanceKind::CoroutineKindShim {
             coroutine_def_id: coroutine_def_id.to_def_id(),
         });
         body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body);
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index b5968517d77..a8b0f4a8d6d 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -168,11 +168,6 @@ impl CoverageCounters {
         self.counter_increment_sites.len()
     }
 
-    #[cfg(test)]
-    pub(super) fn num_expressions(&self) -> usize {
-        self.expressions.len()
-    }
-
     fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> BcbCounter {
         if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) {
             bug!(
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index fd74a2a97e2..360dccb240d 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -14,16 +14,16 @@ use std::ops::{Index, IndexMut};
 /// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s
 /// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s.
 #[derive(Debug)]
-pub(super) struct CoverageGraph {
+pub(crate) struct CoverageGraph {
     bcbs: IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
     bb_to_bcb: IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
-    pub successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
-    pub predecessors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
+    pub(crate) successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
+    pub(crate) predecessors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
     dominators: Option<Dominators<BasicCoverageBlock>>,
 }
 
 impl CoverageGraph {
-    pub fn from_mir(mir_body: &mir::Body<'_>) -> Self {
+    pub(crate) fn from_mir(mir_body: &mir::Body<'_>) -> Self {
         let (bcbs, bb_to_bcb) = Self::compute_basic_coverage_blocks(mir_body);
 
         // Pre-transform MIR `BasicBlock` successors and predecessors into the BasicCoverageBlock
@@ -135,24 +135,28 @@ impl CoverageGraph {
     }
 
     #[inline(always)]
-    pub fn iter_enumerated(
+    pub(crate) fn iter_enumerated(
         &self,
     ) -> impl Iterator<Item = (BasicCoverageBlock, &BasicCoverageBlockData)> {
         self.bcbs.iter_enumerated()
     }
 
     #[inline(always)]
-    pub fn bcb_from_bb(&self, bb: BasicBlock) -> Option<BasicCoverageBlock> {
+    pub(crate) fn bcb_from_bb(&self, bb: BasicBlock) -> Option<BasicCoverageBlock> {
         if bb.index() < self.bb_to_bcb.len() { self.bb_to_bcb[bb] } else { None }
     }
 
     #[inline(always)]
-    pub fn dominates(&self, dom: BasicCoverageBlock, node: BasicCoverageBlock) -> bool {
+    pub(crate) fn dominates(&self, dom: BasicCoverageBlock, node: BasicCoverageBlock) -> bool {
         self.dominators.as_ref().unwrap().dominates(dom, node)
     }
 
     #[inline(always)]
-    pub fn cmp_in_dominator_order(&self, a: BasicCoverageBlock, b: BasicCoverageBlock) -> Ordering {
+    pub(crate) fn cmp_in_dominator_order(
+        &self,
+        a: BasicCoverageBlock,
+        b: BasicCoverageBlock,
+    ) -> Ordering {
         self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
     }
 
@@ -166,7 +170,7 @@ impl CoverageGraph {
     ///
     /// FIXME: That assumption might not be true for [`TerminatorKind::Yield`]?
     #[inline(always)]
-    pub(super) fn bcb_has_multiple_in_edges(&self, bcb: BasicCoverageBlock) -> bool {
+    pub(crate) fn bcb_has_multiple_in_edges(&self, bcb: BasicCoverageBlock) -> bool {
         // Even though bcb0 conceptually has an extra virtual in-edge due to
         // being the entry point, we've already asserted that it has no _other_
         // in-edges, so there's no possibility of it having _multiple_ in-edges.
@@ -212,7 +216,7 @@ impl graph::StartNode for CoverageGraph {
 impl graph::Successors for CoverageGraph {
     #[inline]
     fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
-        self.successors[node].iter().cloned()
+        self.successors[node].iter().copied()
     }
 }
 
@@ -227,7 +231,7 @@ rustc_index::newtype_index! {
     /// A node in the control-flow graph of CoverageGraph.
     #[orderable]
     #[debug_format = "bcb{}"]
-    pub(super) struct BasicCoverageBlock {
+    pub(crate) struct BasicCoverageBlock {
         const START_BCB = 0;
     }
 }
@@ -259,23 +263,23 @@ rustc_index::newtype_index! {
 /// queries (`dominates()`, `predecessors`, `successors`, etc.) have branch (control flow)
 /// significance.
 #[derive(Debug, Clone)]
-pub(super) struct BasicCoverageBlockData {
-    pub basic_blocks: Vec<BasicBlock>,
+pub(crate) struct BasicCoverageBlockData {
+    pub(crate) basic_blocks: Vec<BasicBlock>,
 }
 
 impl BasicCoverageBlockData {
-    pub fn from(basic_blocks: Vec<BasicBlock>) -> Self {
+    fn from(basic_blocks: Vec<BasicBlock>) -> Self {
         assert!(basic_blocks.len() > 0);
         Self { basic_blocks }
     }
 
     #[inline(always)]
-    pub fn leader_bb(&self) -> BasicBlock {
+    pub(crate) fn leader_bb(&self) -> BasicBlock {
         self.basic_blocks[0]
     }
 
     #[inline(always)]
-    pub fn last_bb(&self) -> BasicBlock {
+    pub(crate) fn last_bb(&self) -> BasicBlock {
         *self.basic_blocks.last().unwrap()
     }
 }
@@ -364,7 +368,7 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera
 /// CoverageGraph outside all loops. This supports traversing the BCB CFG in a way that
 /// ensures a loop is completely traversed before processing Blocks after the end of the loop.
 #[derive(Debug)]
-pub(super) struct TraversalContext {
+struct TraversalContext {
     /// BCB with one or more incoming loop backedges, indicating which loop
     /// this context is for.
     ///
@@ -375,7 +379,7 @@ pub(super) struct TraversalContext {
     worklist: VecDeque<BasicCoverageBlock>,
 }
 
-pub(super) struct TraverseCoverageGraphWithLoops<'a> {
+pub(crate) struct TraverseCoverageGraphWithLoops<'a> {
     basic_coverage_blocks: &'a CoverageGraph,
 
     backedges: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
@@ -384,7 +388,7 @@ pub(super) struct TraverseCoverageGraphWithLoops<'a> {
 }
 
 impl<'a> TraverseCoverageGraphWithLoops<'a> {
-    pub(super) fn new(basic_coverage_blocks: &'a CoverageGraph) -> Self {
+    pub(crate) fn new(basic_coverage_blocks: &'a CoverageGraph) -> Self {
         let backedges = find_loop_backedges(basic_coverage_blocks);
 
         let worklist = VecDeque::from([basic_coverage_blocks.start_node()]);
@@ -400,7 +404,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
 
     /// For each loop on the loop context stack (top-down), yields a list of BCBs
     /// within that loop that have an outgoing edge back to the loop header.
-    pub(super) fn reloop_bcbs_per_loop(&self) -> impl Iterator<Item = &[BasicCoverageBlock]> {
+    pub(crate) fn reloop_bcbs_per_loop(&self) -> impl Iterator<Item = &[BasicCoverageBlock]> {
         self.context_stack
             .iter()
             .rev()
@@ -408,39 +412,38 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
             .map(|header_bcb| self.backedges[header_bcb].as_slice())
     }
 
-    pub(super) fn next(&mut self) -> Option<BasicCoverageBlock> {
+    pub(crate) fn next(&mut self) -> Option<BasicCoverageBlock> {
         debug!(
             "TraverseCoverageGraphWithLoops::next - context_stack: {:?}",
             self.context_stack.iter().rev().collect::<Vec<_>>()
         );
 
         while let Some(context) = self.context_stack.last_mut() {
-            if let Some(bcb) = context.worklist.pop_front() {
-                if !self.visited.insert(bcb) {
-                    debug!("Already visited: {bcb:?}");
-                    continue;
-                }
-                debug!("Visiting {bcb:?}");
-
-                if self.backedges[bcb].len() > 0 {
-                    debug!("{bcb:?} is a loop header! Start a new TraversalContext...");
-                    self.context_stack.push(TraversalContext {
-                        loop_header: Some(bcb),
-                        worklist: VecDeque::new(),
-                    });
-                }
-                self.add_successors_to_worklists(bcb);
-                return Some(bcb);
-            } else {
-                // Strip contexts with empty worklists from the top of the stack
+            let Some(bcb) = context.worklist.pop_front() else {
+                // This stack level is exhausted; pop it and try the next one.
                 self.context_stack.pop();
+                continue;
+            };
+
+            if !self.visited.insert(bcb) {
+                debug!("Already visited: {bcb:?}");
+                continue;
+            }
+            debug!("Visiting {bcb:?}");
+
+            if self.backedges[bcb].len() > 0 {
+                debug!("{bcb:?} is a loop header! Start a new TraversalContext...");
+                self.context_stack
+                    .push(TraversalContext { loop_header: Some(bcb), worklist: VecDeque::new() });
             }
+            self.add_successors_to_worklists(bcb);
+            return Some(bcb);
         }
 
         None
     }
 
-    pub fn add_successors_to_worklists(&mut self, bcb: BasicCoverageBlock) {
+    fn add_successors_to_worklists(&mut self, bcb: BasicCoverageBlock) {
         let successors = &self.basic_coverage_blocks.successors[bcb];
         debug!("{:?} has {} successors:", bcb, successors.len());
 
@@ -494,11 +497,11 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
         }
     }
 
-    pub fn is_complete(&self) -> bool {
+    pub(crate) fn is_complete(&self) -> bool {
         self.visited.count() == self.visited.domain_size()
     }
 
-    pub fn unvisited(&self) -> Vec<BasicCoverageBlock> {
+    pub(crate) fn unvisited(&self) -> Vec<BasicCoverageBlock> {
         let mut unvisited_set: BitSet<BasicCoverageBlock> =
             BitSet::new_filled(self.visited.domain_size());
         unvisited_set.subtract(&self.visited);
@@ -506,7 +509,7 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
     }
 }
 
-pub(super) fn find_loop_backedges(
+fn find_loop_backedges(
     basic_coverage_blocks: &CoverageGraph,
 ) -> IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>> {
     let num_bcbs = basic_coverage_blocks.num_nodes();
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 65715253647..25744009be8 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -49,7 +49,7 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// Query implementation for `coverage_ids_info`.
 fn coverage_ids_info<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance_def: ty::InstanceDef<'tcx>,
+    instance_def: ty::InstanceKind<'tcx>,
 ) -> CoverageIdsInfo {
     let mir_body = tcx.instance_mir(instance_def);
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index bb6a666ff73..84a70d1f02d 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,9 +1,15 @@
+use std::collections::VecDeque;
+
+use rustc_data_structures::captures::Captures;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir;
 use rustc_span::Span;
 
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
 use crate::coverage::mappings;
-use crate::coverage::spans::from_mir::SpanFromMir;
+use crate::coverage::spans::from_mir::{
+    extract_covspans_and_holes_from_mir, ExtractedCovspans, Hole, SpanFromMir,
+};
 use crate::coverage::ExtractedHirInfo;
 
 mod from_mir;
@@ -19,50 +25,181 @@ pub(super) fn extract_refined_covspans(
     basic_coverage_blocks: &CoverageGraph,
     code_mappings: &mut impl Extend<mappings::CodeMapping>,
 ) {
-    let sorted_span_buckets =
-        from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks);
-    for bucket in sorted_span_buckets {
-        let refined_spans = refine_sorted_spans(bucket);
-        code_mappings.extend(refined_spans.into_iter().map(|RefinedCovspan { span, bcb }| {
+    let ExtractedCovspans { mut covspans, mut holes } =
+        extract_covspans_and_holes_from_mir(mir_body, hir_info, basic_coverage_blocks);
+
+    // First, perform the passes that need macro information.
+    covspans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb));
+    remove_unwanted_macro_spans(&mut covspans);
+    split_visible_macro_spans(&mut covspans);
+
+    // We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`.
+    let mut covspans = covspans.into_iter().map(SpanFromMir::into_covspan).collect::<Vec<_>>();
+
+    let compare_covspans = |a: &Covspan, b: &Covspan| {
+        compare_spans(a.span, b.span)
+            // After deduplication, we want to keep only the most-dominated BCB.
+            .then_with(|| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
+    };
+    covspans.sort_by(compare_covspans);
+
+    // Among covspans with the same span, keep only one,
+    // preferring the one with the most-dominated BCB.
+    // (Ideally we should try to preserve _all_ non-dominating BCBs, but that
+    // requires a lot more complexity in the span refiner, for little benefit.)
+    covspans.dedup_by(|b, a| a.span.source_equal(b.span));
+
+    // Sort the holes, and merge overlapping/adjacent holes.
+    holes.sort_by(|a, b| compare_spans(a.span, b.span));
+    holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
+
+    // Split the covspans into separate buckets that don't overlap any holes.
+    let buckets = divide_spans_into_buckets(covspans, &holes);
+
+    for mut covspans in buckets {
+        // Make sure each individual bucket is internally sorted.
+        covspans.sort_by(compare_covspans);
+        let _span = debug_span!("processing bucket", ?covspans).entered();
+
+        let mut covspans = remove_unwanted_overlapping_spans(covspans);
+        debug!(?covspans, "after removing overlaps");
+
+        // Do one last merge pass, to simplify the output.
+        covspans.dedup_by(|b, a| a.merge_if_eligible(b));
+        debug!(?covspans, "after merge");
+
+        code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| {
             // Each span produced by the refiner represents an ordinary code region.
             mappings::CodeMapping { span, bcb }
         }));
     }
 }
 
-#[derive(Debug)]
-struct RefinedCovspan {
-    span: Span,
-    bcb: BasicCoverageBlock,
+/// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
+/// multiple condition/consequent blocks that have the span of the whole macro
+/// invocation, which is unhelpful. Keeping only the first such span seems to
+/// give better mappings, so remove the others.
+///
+/// (The input spans should be sorted in BCB dominator order, so that the
+/// retained "first" span is likely to dominate the others.)
+fn remove_unwanted_macro_spans(covspans: &mut Vec<SpanFromMir>) {
+    let mut seen_macro_spans = FxHashSet::default();
+    covspans.retain(|covspan| {
+        // Ignore (retain) non-macro-expansion spans.
+        if covspan.visible_macro.is_none() {
+            return true;
+        }
+
+        // Retain only the first macro-expanded covspan with this span.
+        seen_macro_spans.insert(covspan.span)
+    });
 }
 
-impl RefinedCovspan {
-    fn is_mergeable(&self, other: &Self) -> bool {
-        self.bcb == other.bcb
-    }
+/// When a span corresponds to a macro invocation that is visible from the
+/// function body, split it into two parts. The first part covers just the
+/// macro name plus `!`, and the second part covers the rest of the macro
+/// invocation. This seems to give better results for code that uses macros.
+fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
+    let mut extra_spans = vec![];
 
-    fn merge_from(&mut self, other: &Self) {
-        debug_assert!(self.is_mergeable(other));
-        self.span = self.span.to(other.span);
+    covspans.retain(|covspan| {
+        let Some(visible_macro) = covspan.visible_macro else { return true };
+
+        let split_len = visible_macro.as_str().len() as u32 + 1;
+        let (before, after) = covspan.span.split_at(split_len);
+        if !covspan.span.contains(before) || !covspan.span.contains(after) {
+            // Something is unexpectedly wrong with the split point.
+            // The debug assertion in `split_at` will have already caught this,
+            // but in release builds it's safer to do nothing and maybe get a
+            // bug report for unexpected coverage, rather than risk an ICE.
+            return true;
+        }
+
+        extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb));
+        extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb));
+        false // Discard the original covspan that we just split.
+    });
+
+    // The newly-split spans are added at the end, so any previous sorting
+    // is not preserved.
+    covspans.extend(extra_spans);
+}
+
+/// Uses the holes to divide the given covspans into buckets, such that:
+/// - No span in any hole overlaps a bucket (truncating the spans if necessary).
+/// - The spans in each bucket are strictly after all spans in previous buckets,
+///   and strictly before all spans in subsequent buckets.
+///
+/// The resulting buckets are sorted relative to each other, but might not be
+/// internally sorted.
+#[instrument(level = "debug")]
+fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
+    debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+    debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+
+    // Now we're ready to start carving holes out of the initial coverage spans,
+    // and grouping them in buckets separated by the holes.
+
+    let mut input_covspans = VecDeque::from(input_covspans);
+    let mut fragments = vec![];
+
+    // For each hole:
+    // - Identify the spans that are entirely or partly before the hole.
+    // - Put those spans in a corresponding bucket, truncated to the start of the hole.
+    // - If one of those spans also extends after the hole, put the rest of it
+    //   in a "fragments" vector that is processed by the next hole.
+    let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
+    for (hole, bucket) in holes.iter().zip(&mut buckets) {
+        let fragments_from_prev = std::mem::take(&mut fragments);
+
+        // Only inspect spans that precede or overlap this hole,
+        // leaving the rest to be inspected by later holes.
+        // (This relies on the spans and holes both being sorted.)
+        let relevant_input_covspans =
+            drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi());
+
+        for covspan in fragments_from_prev.into_iter().chain(relevant_input_covspans) {
+            let (before, after) = covspan.split_around_hole_span(hole.span);
+            bucket.extend(before);
+            fragments.extend(after);
+        }
     }
+
+    // After finding the spans before each hole, any remaining fragments/spans
+    // form their own final bucket, after the final hole.
+    // (If there were no holes, this will just be all of the initial spans.)
+    fragments.extend(input_covspans);
+    buckets.push(fragments);
+
+    buckets
+}
+
+/// Similar to `.drain(..)`, but stops just before it would remove an item not
+/// satisfying the predicate.
+fn drain_front_while<'a, T>(
+    queue: &'a mut VecDeque<T>,
+    mut pred_fn: impl FnMut(&T) -> bool,
+) -> impl Iterator<Item = T> + Captures<'a> {
+    std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
 }
 
 /// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
-/// those spans by removing spans that overlap in unwanted ways, and by merging
-/// compatible adjacent spans.
+/// those spans by removing spans that overlap in unwanted ways.
 #[instrument(level = "debug")]
-fn refine_sorted_spans(sorted_spans: Vec<SpanFromMir>) -> Vec<RefinedCovspan> {
+fn remove_unwanted_overlapping_spans(sorted_spans: Vec<Covspan>) -> Vec<Covspan> {
+    debug_assert!(sorted_spans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
+
     // Holds spans that have been read from the input vector, but haven't yet
     // been committed to the output vector.
     let mut pending = vec![];
     let mut refined = vec![];
 
     for curr in sorted_spans {
-        pending.retain(|prev: &SpanFromMir| {
+        pending.retain(|prev: &Covspan| {
             if prev.span.hi() <= curr.span.lo() {
                 // There's no overlap between the previous/current covspans,
                 // so move the previous one into the refined list.
-                refined.push(RefinedCovspan { span: prev.span, bcb: prev.bcb });
+                refined.push(prev.clone());
                 false
             } else {
                 // Otherwise, retain the previous covspan only if it has the
@@ -75,22 +212,57 @@ fn refine_sorted_spans(sorted_spans: Vec<SpanFromMir>) -> Vec<RefinedCovspan> {
     }
 
     // Drain the rest of the pending list into the refined list.
-    for prev in pending {
-        refined.push(RefinedCovspan { span: prev.span, bcb: prev.bcb });
+    refined.extend(pending);
+    refined
+}
+
+#[derive(Clone, Debug)]
+struct Covspan {
+    span: Span,
+    bcb: BasicCoverageBlock,
+}
+
+impl Covspan {
+    /// Splits this covspan into 0-2 parts:
+    /// - The part that is strictly before the hole span, if any.
+    /// - The part that is strictly after the hole span, if any.
+    fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
+        let before = try {
+            let span = self.span.trim_end(hole_span)?;
+            Self { span, ..*self }
+        };
+        let after = try {
+            let span = self.span.trim_start(hole_span)?;
+            Self { span, ..*self }
+        };
+
+        (before, after)
     }
 
-    // Do one last merge pass, to simplify the output.
-    debug!(?refined, "before merge");
-    refined.dedup_by(|b, a| {
-        if a.is_mergeable(b) {
-            debug!(?a, ?b, "merging list-adjacent refined spans");
-            a.merge_from(b);
-            true
-        } else {
-            false
+    /// If `self` and `other` can be merged (i.e. they have the same BCB),
+    /// mutates `self.span` to also include `other.span` and returns true.
+    ///
+    /// Note that compatible covspans can be merged even if their underlying
+    /// spans are not overlapping/adjacent; any space between them will also be
+    /// part of the merged covspan.
+    fn merge_if_eligible(&mut self, other: &Self) -> bool {
+        if self.bcb != other.bcb {
+            return false;
         }
-    });
-    debug!(?refined, "after merge");
 
-    refined
+        self.span = self.span.to(other.span);
+        true
+    }
+}
+
+/// Compares two spans in (lo ascending, hi descending) order.
+fn compare_spans(a: Span, b: Span) -> std::cmp::Ordering {
+    // First sort by span start.
+    Ord::cmp(&a.lo(), &b.lo())
+        // If span starts are the same, sort by span end in reverse order.
+        // This ensures that if spans A and B are adjacent in the list,
+        // and they overlap but are not equal, then either:
+        // - Span A extends further left, or
+        // - Both have the same start and span A extends further right
+        .then_with(|| Ord::cmp(&a.hi(), &b.hi()).reverse())
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index b1f71035dde..09deb7534bf 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -1,7 +1,3 @@
-use std::collections::VecDeque;
-
-use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::{
@@ -13,25 +9,25 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
 use crate::coverage::graph::{
     BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
 };
+use crate::coverage::spans::Covspan;
 use crate::coverage::ExtractedHirInfo;
 
+pub(crate) struct ExtractedCovspans {
+    pub(crate) covspans: Vec<SpanFromMir>,
+    pub(crate) holes: Vec<Hole>,
+}
+
 /// Traverses the MIR body to produce an initial collection of coverage-relevant
 /// spans, each associated with a node in the coverage graph (BCB) and possibly
 /// other metadata.
-///
-/// The returned spans are divided into one or more buckets, such that:
-/// - The spans in each bucket are strictly after all spans in previous buckets,
-///   and strictly before all spans in subsequent buckets.
-/// - The contents of each bucket are also sorted, in a specific order that is
-///   expected by the subsequent span-refinement step.
-pub(super) fn mir_to_initial_sorted_coverage_spans(
+pub(crate) fn extract_covspans_and_holes_from_mir(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
     basic_coverage_blocks: &CoverageGraph,
-) -> Vec<Vec<SpanFromMir>> {
+) -> ExtractedCovspans {
     let &ExtractedHirInfo { body_span, .. } = hir_info;
 
-    let mut initial_spans = vec![];
+    let mut covspans = vec![];
     let mut holes = vec![];
 
     for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() {
@@ -40,150 +36,21 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
             body_span,
             bcb,
             bcb_data,
-            &mut initial_spans,
+            &mut covspans,
             &mut holes,
         );
     }
 
     // Only add the signature span if we found at least one span in the body.
-    if !initial_spans.is_empty() || !holes.is_empty() {
+    if !covspans.is_empty() || !holes.is_empty() {
         // If there is no usable signature span, add a fake one (before refinement)
         // to avoid an ugly gap between the body start and the first real span.
         // FIXME: Find a more principled way to solve this problem.
         let fn_sig_span = hir_info.fn_sig_span_extended.unwrap_or_else(|| body_span.shrink_to_lo());
-        initial_spans.push(SpanFromMir::for_fn_sig(fn_sig_span));
-    }
-
-    initial_spans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb));
-    remove_unwanted_macro_spans(&mut initial_spans);
-    split_visible_macro_spans(&mut initial_spans);
-
-    let compare_covspans = |a: &SpanFromMir, b: &SpanFromMir| {
-        compare_spans(a.span, b.span)
-            // After deduplication, we want to keep only the most-dominated BCB.
-            .then_with(|| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
-    };
-    initial_spans.sort_by(compare_covspans);
-
-    // Among covspans with the same span, keep only one,
-    // preferring the one with the most-dominated BCB.
-    // (Ideally we should try to preserve _all_ non-dominating BCBs, but that
-    // requires a lot more complexity in the span refiner, for little benefit.)
-    initial_spans.dedup_by(|b, a| a.span.source_equal(b.span));
-
-    // Sort the holes, and merge overlapping/adjacent holes.
-    holes.sort_by(|a, b| compare_spans(a.span, b.span));
-    holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
-
-    // Now we're ready to start carving holes out of the initial coverage spans,
-    // and grouping them in buckets separated by the holes.
-
-    let mut initial_spans = VecDeque::from(initial_spans);
-    let mut fragments: Vec<SpanFromMir> = vec![];
-
-    // For each hole:
-    // - Identify the spans that are entirely or partly before the hole.
-    // - Put those spans in a corresponding bucket, truncated to the start of the hole.
-    // - If one of those spans also extends after the hole, put the rest of it
-    //   in a "fragments" vector that is processed by the next hole.
-    let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
-    for (hole, bucket) in holes.iter().zip(&mut buckets) {
-        let fragments_from_prev = std::mem::take(&mut fragments);
-
-        // Only inspect spans that precede or overlap this hole,
-        // leaving the rest to be inspected by later holes.
-        // (This relies on the spans and holes both being sorted.)
-        let relevant_initial_spans =
-            drain_front_while(&mut initial_spans, |c| c.span.lo() < hole.span.hi());
-
-        for covspan in fragments_from_prev.into_iter().chain(relevant_initial_spans) {
-            let (before, after) = covspan.split_around_hole_span(hole.span);
-            bucket.extend(before);
-            fragments.extend(after);
-        }
+        covspans.push(SpanFromMir::for_fn_sig(fn_sig_span));
     }
 
-    // After finding the spans before each hole, any remaining fragments/spans
-    // form their own final bucket, after the final hole.
-    // (If there were no holes, this will just be all of the initial spans.)
-    fragments.extend(initial_spans);
-    buckets.push(fragments);
-
-    // Make sure each individual bucket is still internally sorted.
-    for bucket in &mut buckets {
-        bucket.sort_by(compare_covspans);
-    }
-    buckets
-}
-
-fn compare_spans(a: Span, b: Span) -> std::cmp::Ordering {
-    // First sort by span start.
-    Ord::cmp(&a.lo(), &b.lo())
-        // If span starts are the same, sort by span end in reverse order.
-        // This ensures that if spans A and B are adjacent in the list,
-        // and they overlap but are not equal, then either:
-        // - Span A extends further left, or
-        // - Both have the same start and span A extends further right
-        .then_with(|| Ord::cmp(&a.hi(), &b.hi()).reverse())
-}
-
-/// Similar to `.drain(..)`, but stops just before it would remove an item not
-/// satisfying the predicate.
-fn drain_front_while<'a, T>(
-    queue: &'a mut VecDeque<T>,
-    mut pred_fn: impl FnMut(&T) -> bool,
-) -> impl Iterator<Item = T> + Captures<'a> {
-    std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
-}
-
-/// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
-/// multiple condition/consequent blocks that have the span of the whole macro
-/// invocation, which is unhelpful. Keeping only the first such span seems to
-/// give better mappings, so remove the others.
-///
-/// (The input spans should be sorted in BCB dominator order, so that the
-/// retained "first" span is likely to dominate the others.)
-fn remove_unwanted_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
-    let mut seen_macro_spans = FxHashSet::default();
-    initial_spans.retain(|covspan| {
-        // Ignore (retain) non-macro-expansion spans.
-        if covspan.visible_macro.is_none() {
-            return true;
-        }
-
-        // Retain only the first macro-expanded covspan with this span.
-        seen_macro_spans.insert(covspan.span)
-    });
-}
-
-/// When a span corresponds to a macro invocation that is visible from the
-/// function body, split it into two parts. The first part covers just the
-/// macro name plus `!`, and the second part covers the rest of the macro
-/// invocation. This seems to give better results for code that uses macros.
-fn split_visible_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
-    let mut extra_spans = vec![];
-
-    initial_spans.retain(|covspan| {
-        let Some(visible_macro) = covspan.visible_macro else { return true };
-
-        let split_len = visible_macro.as_str().len() as u32 + 1;
-        let (before, after) = covspan.span.split_at(split_len);
-        if !covspan.span.contains(before) || !covspan.span.contains(after) {
-            // Something is unexpectedly wrong with the split point.
-            // The debug assertion in `split_at` will have already caught this,
-            // but in release builds it's safer to do nothing and maybe get a
-            // bug report for unexpected coverage, rather than risk an ICE.
-            return true;
-        }
-
-        extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb));
-        extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb));
-        false // Discard the original covspan that we just split.
-    });
-
-    // The newly-split spans are added at the end, so any previous sorting
-    // is not preserved.
-    initial_spans.extend(extra_spans);
+    ExtractedCovspans { covspans, holes }
 }
 
 // Generate a set of coverage spans from the filtered set of `Statement`s and `Terminator`s of
@@ -402,12 +269,12 @@ fn unexpand_into_body_span_with_prev(
 }
 
 #[derive(Debug)]
-struct Hole {
-    span: Span,
+pub(crate) struct Hole {
+    pub(crate) span: Span,
 }
 
 impl Hole {
-    fn merge_if_overlapping_or_adjacent(&mut self, other: &mut Self) -> bool {
+    pub(crate) fn merge_if_overlapping_or_adjacent(&mut self, other: &mut Self) -> bool {
         if !self.span.overlaps_or_adjacent(other.span) {
             return false;
         }
@@ -418,7 +285,7 @@ impl Hole {
 }
 
 #[derive(Debug)]
-pub(super) struct SpanFromMir {
+pub(crate) struct SpanFromMir {
     /// A span that has been extracted from MIR and then "un-expanded" back to
     /// within the current function's `body_span`. After various intermediate
     /// processing steps, this span is emitted as part of the final coverage
@@ -426,9 +293,9 @@ pub(super) struct SpanFromMir {
     ///
     /// With the exception of `fn_sig_span`, this should always be contained
     /// within `body_span`.
-    pub(super) span: Span,
-    visible_macro: Option<Symbol>,
-    pub(super) bcb: BasicCoverageBlock,
+    pub(crate) span: Span,
+    pub(crate) visible_macro: Option<Symbol>,
+    pub(crate) bcb: BasicCoverageBlock,
 }
 
 impl SpanFromMir {
@@ -436,23 +303,12 @@ impl SpanFromMir {
         Self::new(fn_sig_span, None, START_BCB)
     }
 
-    fn new(span: Span, visible_macro: Option<Symbol>, bcb: BasicCoverageBlock) -> Self {
+    pub(crate) fn new(span: Span, visible_macro: Option<Symbol>, bcb: BasicCoverageBlock) -> Self {
         Self { span, visible_macro, bcb }
     }
 
-    /// Splits this span into 0-2 parts:
-    /// - The part that is strictly before the hole span, if any.
-    /// - The part that is strictly after the hole span, if any.
-    fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
-        let before = try {
-            let span = self.span.trim_end(hole_span)?;
-            Self { span, ..*self }
-        };
-        let after = try {
-            let span = self.span.trim_start(hole_span)?;
-            Self { span, ..*self }
-        };
-
-        (before, after)
+    pub(crate) fn into_covspan(self) -> Covspan {
+        let Self { span, visible_macro: _, bcb } = self;
+        Covspan { span, bcb }
     }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index ca64688e6b8..048547dc9f5 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -24,7 +24,6 @@
 //! globals is comparatively simpler. The easiest way is to wrap the test in a closure argument
 //! to: `rustc_span::create_default_session_globals_then(|| { test_here(); })`.
 
-use super::counters;
 use super::graph::{self, BasicCoverageBlock};
 
 use itertools::Itertools;
@@ -551,108 +550,3 @@ fn test_covgraph_switchint_loop_then_inner_loop_else_break() {
     assert_successors(&basic_coverage_blocks, bcb(5), &[bcb(1)]);
     assert_successors(&basic_coverage_blocks, bcb(6), &[bcb(4)]);
 }
-
-#[test]
-fn test_find_loop_backedges_none() {
-    let mir_body = goto_switchint();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    if false {
-        eprintln!(
-            "basic_coverage_blocks = {:?}",
-            basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
-        );
-        eprintln!("successors = {:?}", basic_coverage_blocks.successors);
-    }
-    let backedges = graph::find_loop_backedges(&basic_coverage_blocks);
-    assert_eq!(
-        backedges.iter_enumerated().map(|(_bcb, backedges)| backedges.len()).sum::<usize>(),
-        0,
-        "backedges: {:?}",
-        backedges
-    );
-}
-
-#[test]
-fn test_find_loop_backedges_one() {
-    let mir_body = switchint_then_loop_else_return();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    let backedges = graph::find_loop_backedges(&basic_coverage_blocks);
-    assert_eq!(
-        backedges.iter_enumerated().map(|(_bcb, backedges)| backedges.len()).sum::<usize>(),
-        1,
-        "backedges: {:?}",
-        backedges
-    );
-
-    assert_eq!(backedges[bcb(1)], &[bcb(3)]);
-}
-
-#[test]
-fn test_find_loop_backedges_two() {
-    let mir_body = switchint_loop_then_inner_loop_else_break();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    let backedges = graph::find_loop_backedges(&basic_coverage_blocks);
-    assert_eq!(
-        backedges.iter_enumerated().map(|(_bcb, backedges)| backedges.len()).sum::<usize>(),
-        2,
-        "backedges: {:?}",
-        backedges
-    );
-
-    assert_eq!(backedges[bcb(1)], &[bcb(5)]);
-    assert_eq!(backedges[bcb(4)], &[bcb(6)]);
-}
-
-#[test]
-fn test_traverse_coverage_with_loops() {
-    let mir_body = switchint_loop_then_inner_loop_else_break();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    let mut traversed_in_order = Vec::new();
-    let mut traversal = graph::TraverseCoverageGraphWithLoops::new(&basic_coverage_blocks);
-    while let Some(bcb) = traversal.next() {
-        traversed_in_order.push(bcb);
-    }
-
-    // bcb0 is visited first. Then bcb1 starts the first loop, and all remaining nodes, *except*
-    // bcb6 are inside the first loop.
-    assert_eq!(
-        *traversed_in_order.last().expect("should have elements"),
-        bcb(6),
-        "bcb6 should not be visited until all nodes inside the first loop have been visited"
-    );
-}
-
-#[test]
-fn test_make_bcb_counters() {
-    rustc_span::create_default_session_globals_then(|| {
-        let mir_body = goto_switchint();
-        let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-        // Historically this test would use `spans` internals to set up fake
-        // coverage spans for BCBs 1 and 2. Now we skip that step and just tell
-        // BCB counter construction that those BCBs have spans.
-        let bcb_has_coverage_spans = |bcb: BasicCoverageBlock| (1..=2).contains(&bcb.as_usize());
-        let coverage_counters = counters::CoverageCounters::make_bcb_counters(
-            &basic_coverage_blocks,
-            bcb_has_coverage_spans,
-        );
-        assert_eq!(coverage_counters.num_expressions(), 0);
-
-        assert_eq!(
-            0, // bcb1 has a `Counter` with id = 0
-            match coverage_counters.bcb_counter(bcb(1)).expect("should have a counter") {
-                counters::BcbCounter::Counter { id, .. } => id,
-                _ => panic!("expected a Counter"),
-            }
-            .as_u32()
-        );
-
-        assert_eq!(
-            1, // bcb2 has a `Counter` with id = 1
-            match coverage_counters.bcb_counter(bcb(2)).expect("should have a counter") {
-                counters::BcbCounter::Counter { id, .. } => id,
-                _ => panic!("expected a Counter"),
-            }
-            .as_u32()
-        );
-    });
-}
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 2cbe0a01e9e..d04bb8d302e 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -10,7 +10,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::TypeVisitableExt;
-use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt};
 use rustc_session::config::{DebugInfo, OptLevel};
 use rustc_span::source_map::Spanned;
 use rustc_span::sym;
@@ -293,7 +293,7 @@ impl<'tcx> Inliner<'tcx> {
         }
 
         match callee.def {
-            InstanceDef::Item(_) => {
+            InstanceKind::Item(_) => {
                 // If there is no MIR available (either because it was not in metadata or
                 // because it has no MIR because it's an extern function), then the inliner
                 // won't cause cycles on this.
@@ -302,24 +302,24 @@ impl<'tcx> Inliner<'tcx> {
                 }
             }
             // These have no own callable MIR.
-            InstanceDef::Intrinsic(_) | InstanceDef::Virtual(..) => {
+            InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => {
                 return Err("instance without MIR (intrinsic / virtual)");
             }
             // This cannot result in an immediate cycle since the callee MIR is a shim, which does
             // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we
             // do not need to catch this here, we can wait until the inliner decides to continue
             // inlining a second time.
-            InstanceDef::VTableShim(_)
-            | InstanceDef::ReifyShim(..)
-            | InstanceDef::FnPtrShim(..)
-            | InstanceDef::ClosureOnceShim { .. }
-            | InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | InstanceDef::CoroutineKindShim { .. }
-            | InstanceDef::DropGlue(..)
-            | InstanceDef::CloneShim(..)
-            | InstanceDef::ThreadLocalShim(..)
-            | InstanceDef::FnPtrAddrShim(..)
-            | InstanceDef::AsyncDropGlueCtorShim(..) => return Ok(()),
+            InstanceKind::VTableShim(_)
+            | InstanceKind::ReifyShim(..)
+            | InstanceKind::FnPtrShim(..)
+            | InstanceKind::ClosureOnceShim { .. }
+            | InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | InstanceKind::CoroutineKindShim { .. }
+            | InstanceKind::DropGlue(..)
+            | InstanceKind::CloneShim(..)
+            | InstanceKind::ThreadLocalShim(..)
+            | InstanceKind::FnPtrAddrShim(..)
+            | InstanceKind::AsyncDropGlueCtorShim(..) => return Ok(()),
         }
 
         if self.tcx.is_constructor(callee_def_id) {
@@ -372,7 +372,7 @@ impl<'tcx> Inliner<'tcx> {
                 let callee =
                     Instance::resolve(self.tcx, self.param_env, def_id, args).ok().flatten()?;
 
-                if let InstanceDef::Virtual(..) | InstanceDef::Intrinsic(_) = callee.def {
+                if let InstanceKind::Virtual(..) | InstanceKind::Intrinsic(_) = callee.def {
                     return None;
                 }
 
@@ -384,7 +384,7 @@ impl<'tcx> Inliner<'tcx> {
 
                 // Additionally, check that the body that we're inlining actually agrees
                 // with the ABI of the trait that the item comes from.
-                if let InstanceDef::Item(instance_def_id) = callee.def
+                if let InstanceKind::Item(instance_def_id) = callee.def
                     && self.tcx.def_kind(instance_def_id) == DefKind::AssocFn
                     && let instance_fn_sig = self.tcx.fn_sig(instance_def_id).skip_binder()
                     && instance_fn_sig.abi() != fn_sig.abi()
@@ -1063,10 +1063,10 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
 #[instrument(skip(tcx), level = "debug")]
 fn try_instance_mir<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: InstanceDef<'tcx>,
+    instance: InstanceKind<'tcx>,
 ) -> Result<&'tcx Body<'tcx>, &'static str> {
-    if let ty::InstanceDef::DropGlue(_, Some(ty))
-    | ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) = instance
+    if let ty::InstanceKind::DropGlue(_, Some(ty))
+    | ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) = instance
         && let ty::Adt(def, args) = ty.kind()
     {
         let fields = def.all_fields();
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 8c5f965108b..35bcd24ce95 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::mir::TerminatorKind;
 use rustc_middle::ty::TypeVisitableExt;
-use rustc_middle::ty::{self, GenericArgsRef, InstanceDef, TyCtxt};
+use rustc_middle::ty::{self, GenericArgsRef, InstanceKind, TyCtxt};
 use rustc_session::Limit;
 use rustc_span::sym;
 
@@ -22,7 +22,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
         "you should not call `mir_callgraph_reachable` on immediate self recursion"
     );
     assert!(
-        matches!(root.def, InstanceDef::Item(_)),
+        matches!(root.def, InstanceKind::Item(_)),
         "you should not call `mir_callgraph_reachable` on shims"
     );
     assert!(
@@ -70,7 +70,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
             }
 
             match callee.def {
-                InstanceDef::Item(_) => {
+                InstanceKind::Item(_) => {
                     // If there is no MIR available (either because it was not in metadata or
                     // because it has no MIR because it's an extern function), then the inliner
                     // won't cause cycles on this.
@@ -80,24 +80,24 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
                     }
                 }
                 // These have no own callable MIR.
-                InstanceDef::Intrinsic(_) | InstanceDef::Virtual(..) => continue,
+                InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => continue,
                 // These have MIR and if that MIR is inlined, instantiated and then inlining is run
                 // again, a function item can end up getting inlined. Thus we'll be able to cause
                 // a cycle that way
-                InstanceDef::VTableShim(_)
-                | InstanceDef::ReifyShim(..)
-                | InstanceDef::FnPtrShim(..)
-                | InstanceDef::ClosureOnceShim { .. }
-                | InstanceDef::ConstructCoroutineInClosureShim { .. }
-                | InstanceDef::CoroutineKindShim { .. }
-                | InstanceDef::ThreadLocalShim { .. }
-                | InstanceDef::CloneShim(..) => {}
+                InstanceKind::VTableShim(_)
+                | InstanceKind::ReifyShim(..)
+                | InstanceKind::FnPtrShim(..)
+                | InstanceKind::ClosureOnceShim { .. }
+                | InstanceKind::ConstructCoroutineInClosureShim { .. }
+                | InstanceKind::CoroutineKindShim { .. }
+                | InstanceKind::ThreadLocalShim { .. }
+                | InstanceKind::CloneShim(..) => {}
 
                 // This shim does not call any other functions, thus there can be no recursion.
-                InstanceDef::FnPtrAddrShim(..) => {
+                InstanceKind::FnPtrAddrShim(..) => {
                     continue;
                 }
-                InstanceDef::DropGlue(..) | InstanceDef::AsyncDropGlueCtorShim(..) => {
+                InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) => {
                     // FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to
                     // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this
                     // needs some more analysis.
@@ -151,12 +151,12 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
 
 pub(crate) fn mir_inliner_callees<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: ty::InstanceDef<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
 ) -> &'tcx [(DefId, GenericArgsRef<'tcx>)] {
     let steal;
     let guard;
     let body = match (instance, instance.def_id().as_local()) {
-        (InstanceDef::Item(_), Some(def_id)) => {
+        (InstanceKind::Item(_), Some(def_id)) => {
             steal = tcx.mir_promoted(def_id).0;
             guard = steal.borrow();
             &*guard
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 3c0f4e9142b..afba6781a70 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -398,7 +398,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     if is_fn_like {
         // Do not compute the mir call graph without said call graph actually being used.
         if pm::should_run_pass(tcx, &inline::Inline) {
-            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id()));
+            tcx.ensure_with_value().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index d03c2d18c0c..825f8957187 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -29,16 +29,16 @@ pub fn provide(providers: &mut Providers) {
     providers.mir_shims = make_shim;
 }
 
-fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'tcx> {
+fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body<'tcx> {
     debug!("make_shim({:?})", instance);
 
     let mut result = match instance {
-        ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
-        ty::InstanceDef::VTableShim(def_id) => {
+        ty::InstanceKind::Item(..) => bug!("item {:?} passed to make_shim", instance),
+        ty::InstanceKind::VTableShim(def_id) => {
             let adjustment = Adjustment::Deref { source: DerefSource::MutPtr };
             build_call_shim(tcx, instance, Some(adjustment), CallKind::Direct(def_id))
         }
-        ty::InstanceDef::FnPtrShim(def_id, ty) => {
+        ty::InstanceKind::FnPtrShim(def_id, ty) => {
             let trait_ = tcx.trait_of_item(def_id).unwrap();
             // Supports `Fn` or `async Fn` traits.
             let adjustment = match tcx
@@ -58,10 +58,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
         // a virtual call, or a direct call to a function for which
         // indirect calls must be codegen'd differently than direct ones
         // (such as `#[track_caller]`).
-        ty::InstanceDef::ReifyShim(def_id, _) => {
+        ty::InstanceKind::ReifyShim(def_id, _) => {
             build_call_shim(tcx, instance, None, CallKind::Direct(def_id))
         }
-        ty::InstanceDef::ClosureOnceShim { call_once: _, track_caller: _ } => {
+        ty::InstanceKind::ClosureOnceShim { call_once: _, track_caller: _ } => {
             let fn_mut = tcx.require_lang_item(LangItem::FnMut, None);
             let call_mut = tcx
                 .associated_items(fn_mut)
@@ -73,16 +73,16 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
             build_call_shim(tcx, instance, Some(Adjustment::RefMut), CallKind::Direct(call_mut))
         }
 
-        ty::InstanceDef::ConstructCoroutineInClosureShim {
+        ty::InstanceKind::ConstructCoroutineInClosureShim {
             coroutine_closure_def_id,
             receiver_by_ref,
         } => build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref),
 
-        ty::InstanceDef::CoroutineKindShim { coroutine_def_id } => {
+        ty::InstanceKind::CoroutineKindShim { coroutine_def_id } => {
             return tcx.optimized_mir(coroutine_def_id).coroutine_by_move_body().unwrap().clone();
         }
 
-        ty::InstanceDef::DropGlue(def_id, ty) => {
+        ty::InstanceKind::DropGlue(def_id, ty) => {
             // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end
             // of this function. Is this intentional?
             if let Some(ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) {
@@ -127,16 +127,16 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
 
             build_drop_shim(tcx, def_id, ty)
         }
-        ty::InstanceDef::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance),
-        ty::InstanceDef::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty),
-        ty::InstanceDef::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty),
-        ty::InstanceDef::AsyncDropGlueCtorShim(def_id, ty) => {
+        ty::InstanceKind::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance),
+        ty::InstanceKind::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty),
+        ty::InstanceKind::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty),
+        ty::InstanceKind::AsyncDropGlueCtorShim(def_id, ty) => {
             async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty)
         }
-        ty::InstanceDef::Virtual(..) => {
-            bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance)
+        ty::InstanceKind::Virtual(..) => {
+            bug!("InstanceKind::Virtual ({:?}) is for direct calls only", instance)
         }
-        ty::InstanceDef::Intrinsic(_) => {
+        ty::InstanceKind::Intrinsic(_) => {
             bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
         }
     };
@@ -240,7 +240,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
     block(&mut blocks, TerminatorKind::Goto { target: return_block });
     block(&mut blocks, TerminatorKind::Return);
 
-    let source = MirSource::from_instance(ty::InstanceDef::DropGlue(def_id, ty));
+    let source = MirSource::from_instance(ty::InstanceKind::DropGlue(def_id, ty));
     let mut body =
         new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
 
@@ -392,7 +392,10 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
     }
 }
 
-fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'tcx> {
+fn build_thread_local_shim<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
+) -> Body<'tcx> {
     let def_id = instance.def_id();
 
     let span = tcx.def_span(def_id);
@@ -472,7 +475,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
     }
 
     fn into_mir(self) -> Body<'tcx> {
-        let source = MirSource::from_instance(ty::InstanceDef::CloneShim(
+        let source = MirSource::from_instance(ty::InstanceKind::CloneShim(
             self.def_id,
             self.sig.inputs_and_output[0],
         ));
@@ -682,14 +685,14 @@ impl<'tcx> CloneShimBuilder<'tcx> {
 #[instrument(level = "debug", skip(tcx), ret)]
 fn build_call_shim<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: ty::InstanceDef<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
     rcvr_adjustment: Option<Adjustment>,
     call_kind: CallKind<'tcx>,
 ) -> Body<'tcx> {
     // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used
     // to instantiate into the signature of the shim. It is not necessary for users of this
-    // MIR body to perform further instantiations (see `InstanceDef::has_polymorphic_mir_body`).
-    let (sig_args, untuple_args) = if let ty::InstanceDef::FnPtrShim(_, ty) = instance {
+    // MIR body to perform further instantiations (see `InstanceKind::has_polymorphic_mir_body`).
+    let (sig_args, untuple_args) = if let ty::InstanceKind::FnPtrShim(_, ty) = instance {
         let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx));
 
         let untuple_args = sig.inputs();
@@ -741,8 +744,8 @@ fn build_call_shim<'tcx>(
     }
 
     // FIXME(eddyb) avoid having this snippet both here and in
-    // `Instance::fn_sig` (introduce `InstanceDef::fn_sig`?).
-    if let ty::InstanceDef::VTableShim(..) = instance {
+    // `Instance::fn_sig` (introduce `InstanceKind::fn_sig`?).
+    if let ty::InstanceKind::VTableShim(..) = instance {
         // Modify fn(self, ...) to fn(self: *mut Self, ...)
         let mut inputs_and_output = sig.inputs_and_output.to_vec();
         let self_arg = &mut inputs_and_output[0];
@@ -1007,7 +1010,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t
         terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
         is_cleanup: false,
     };
-    let source = MirSource::from_instance(ty::InstanceDef::FnPtrAddrShim(def_id, self_ty));
+    let source = MirSource::from_instance(ty::InstanceKind::FnPtrAddrShim(def_id, self_ty));
     new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span)
 }
 
@@ -1087,7 +1090,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
         is_cleanup: false,
     };
 
-    let source = MirSource::from_instance(ty::InstanceDef::ConstructCoroutineInClosureShim {
+    let source = MirSource::from_instance(ty::InstanceKind::ConstructCoroutineInClosureShim {
         coroutine_closure_def_id,
         receiver_by_ref,
     });
diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
index 41643f20285..ea4f5fca59e 100644
--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
@@ -529,7 +529,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
 
         last_bb.terminator = Some(Terminator { source_info, kind: TerminatorKind::Return });
 
-        let source = MirSource::from_instance(ty::InstanceDef::AsyncDropGlueCtorShim(
+        let source = MirSource::from_instance(ty::InstanceKind::AsyncDropGlueCtorShim(
             self.def_id,
             self.self_ty,
         ));
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index ea23bbc2a38..2cca1a6f507 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{
-    self, CoroutineArgsExt, InstanceDef, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
+    self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
     Variance,
 };
 use rustc_middle::{bug, span_bug};
@@ -44,7 +44,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
         // terribly important that they pass the validator. However, I think other passes might
         // still see them, in which case they might be surprised. It would probably be better if we
         // didn't put this through the MIR pipeline at all.
-        if matches!(body.source.instance, InstanceDef::Intrinsic(..) | InstanceDef::Virtual(..)) {
+        if matches!(body.source.instance, InstanceKind::Intrinsic(..) | InstanceKind::Virtual(..)) {
             return;
         }
         let def_id = body.source.def_id();
@@ -95,7 +95,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
         }
 
         if let MirPhase::Runtime(_) = body.phase {
-            if let ty::InstanceDef::Item(_) = body.source.instance {
+            if let ty::InstanceKind::Item(_) = body.source.instance {
                 if body.has_free_regions() {
                     cfg_checker.fail(
                         Location::START,
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 04de1654c1a..235743fccc8 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -224,7 +224,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
-    self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable,
+    self, AssocKind, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable,
     TypeVisitableExt, VtblEntry,
 };
 use rustc_middle::ty::{GenericArgKind, GenericArgs};
@@ -420,7 +420,7 @@ fn collect_items_rec<'tcx>(
                     used_items.push(respan(
                         starting_item.span,
                         MonoItem::Fn(Instance {
-                            def: InstanceDef::ThreadLocalShim(def_id),
+                            def: InstanceKind::ThreadLocalShim(def_id),
                             args: GenericArgs::empty(),
                         }),
                     ));
@@ -938,7 +938,7 @@ fn visit_instance_use<'tcx>(
     if !should_codegen_locally(tcx, instance) {
         return;
     }
-    if let ty::InstanceDef::Intrinsic(def_id) = instance.def {
+    if let ty::InstanceKind::Intrinsic(def_id) = instance.def {
         let name = tcx.item_name(def_id);
         if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) {
             // The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will
@@ -960,31 +960,31 @@ fn visit_instance_use<'tcx>(
     }
 
     match instance.def {
-        ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => {
+        ty::InstanceKind::Virtual(..) | ty::InstanceKind::Intrinsic(_) => {
             if !is_direct_call {
                 bug!("{:?} being reified", instance);
             }
         }
-        ty::InstanceDef::ThreadLocalShim(..) => {
+        ty::InstanceKind::ThreadLocalShim(..) => {
             bug!("{:?} being reified", instance);
         }
-        ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => {
+        ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => {
             // Don't need to emit noop drop glue if we are calling directly.
             if !is_direct_call {
                 output.push(create_fn_mono_item(tcx, instance, source));
             }
         }
-        ty::InstanceDef::DropGlue(_, Some(_))
-        | ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_))
-        | ty::InstanceDef::VTableShim(..)
-        | ty::InstanceDef::ReifyShim(..)
-        | ty::InstanceDef::ClosureOnceShim { .. }
-        | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-        | ty::InstanceDef::CoroutineKindShim { .. }
-        | ty::InstanceDef::Item(..)
-        | ty::InstanceDef::FnPtrShim(..)
-        | ty::InstanceDef::CloneShim(..)
-        | ty::InstanceDef::FnPtrAddrShim(..) => {
+        ty::InstanceKind::DropGlue(_, Some(_))
+        | ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(_))
+        | ty::InstanceKind::VTableShim(..)
+        | ty::InstanceKind::ReifyShim(..)
+        | ty::InstanceKind::ClosureOnceShim { .. }
+        | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+        | ty::InstanceKind::CoroutineKindShim { .. }
+        | ty::InstanceKind::Item(..)
+        | ty::InstanceKind::FnPtrShim(..)
+        | ty::InstanceKind::CloneShim(..)
+        | ty::InstanceKind::FnPtrAddrShim(..) => {
             output.push(create_fn_mono_item(tcx, instance, source));
         }
     }
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 14b5b22dc64..9a7c488833a 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -114,7 +114,7 @@ use rustc_middle::mir::mono::{
 };
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
-use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt};
+use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceKind, TyCtxt};
 use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
 use rustc_session::CodegenUnits;
 use rustc_span::symbol::Symbol;
@@ -620,20 +620,20 @@ fn characteristic_def_id_of_mono_item<'tcx>(
     match mono_item {
         MonoItem::Fn(instance) => {
             let def_id = match instance.def {
-                ty::InstanceDef::Item(def) => def,
-                ty::InstanceDef::VTableShim(..)
-                | ty::InstanceDef::ReifyShim(..)
-                | ty::InstanceDef::FnPtrShim(..)
-                | ty::InstanceDef::ClosureOnceShim { .. }
-                | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-                | ty::InstanceDef::CoroutineKindShim { .. }
-                | ty::InstanceDef::Intrinsic(..)
-                | ty::InstanceDef::DropGlue(..)
-                | ty::InstanceDef::Virtual(..)
-                | ty::InstanceDef::CloneShim(..)
-                | ty::InstanceDef::ThreadLocalShim(..)
-                | ty::InstanceDef::FnPtrAddrShim(..)
-                | ty::InstanceDef::AsyncDropGlueCtorShim(..) => return None,
+                ty::InstanceKind::Item(def) => def,
+                ty::InstanceKind::VTableShim(..)
+                | ty::InstanceKind::ReifyShim(..)
+                | ty::InstanceKind::FnPtrShim(..)
+                | ty::InstanceKind::ClosureOnceShim { .. }
+                | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+                | ty::InstanceKind::CoroutineKindShim { .. }
+                | ty::InstanceKind::Intrinsic(..)
+                | ty::InstanceKind::DropGlue(..)
+                | ty::InstanceKind::Virtual(..)
+                | ty::InstanceKind::CloneShim(..)
+                | ty::InstanceKind::ThreadLocalShim(..)
+                | ty::InstanceKind::FnPtrAddrShim(..)
+                | ty::InstanceKind::AsyncDropGlueCtorShim(..) => return None,
             };
 
             // If this is a method, we want to put it into the same module as
@@ -777,28 +777,28 @@ fn mono_item_visibility<'tcx>(
     };
 
     let def_id = match instance.def {
-        InstanceDef::Item(def_id)
-        | InstanceDef::DropGlue(def_id, Some(_))
-        | InstanceDef::AsyncDropGlueCtorShim(def_id, Some(_)) => def_id,
+        InstanceKind::Item(def_id)
+        | InstanceKind::DropGlue(def_id, Some(_))
+        | InstanceKind::AsyncDropGlueCtorShim(def_id, Some(_)) => def_id,
 
         // We match the visibility of statics here
-        InstanceDef::ThreadLocalShim(def_id) => {
+        InstanceKind::ThreadLocalShim(def_id) => {
             return static_visibility(tcx, can_be_internalized, def_id);
         }
 
         // These are all compiler glue and such, never exported, always hidden.
-        InstanceDef::VTableShim(..)
-        | InstanceDef::ReifyShim(..)
-        | InstanceDef::FnPtrShim(..)
-        | InstanceDef::Virtual(..)
-        | InstanceDef::Intrinsic(..)
-        | InstanceDef::ClosureOnceShim { .. }
-        | InstanceDef::ConstructCoroutineInClosureShim { .. }
-        | InstanceDef::CoroutineKindShim { .. }
-        | InstanceDef::DropGlue(..)
-        | InstanceDef::AsyncDropGlueCtorShim(..)
-        | InstanceDef::CloneShim(..)
-        | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
+        InstanceKind::VTableShim(..)
+        | InstanceKind::ReifyShim(..)
+        | InstanceKind::FnPtrShim(..)
+        | InstanceKind::Virtual(..)
+        | InstanceKind::Intrinsic(..)
+        | InstanceKind::ClosureOnceShim { .. }
+        | InstanceKind::ConstructCoroutineInClosureShim { .. }
+        | InstanceKind::CoroutineKindShim { .. }
+        | InstanceKind::DropGlue(..)
+        | InstanceKind::AsyncDropGlueCtorShim(..)
+        | InstanceKind::CloneShim(..)
+        | InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden,
     };
 
     // The `start_fn` lang item is actually a monomorphized instance of a
@@ -813,7 +813,7 @@ fn mono_item_visibility<'tcx>(
     //        internalization, but we have to understand that it's referenced
     //        from the `main` symbol we'll generate later.
     //
-    //        This may be fixable with a new `InstanceDef` perhaps? Unsure!
+    //        This may be fixable with a new `InstanceKind` perhaps? Unsure!
     if tcx.is_lang_item(def_id, LangItem::Start) {
         *can_be_internalized = false;
         return Visibility::Hidden;
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index c187cb63ee1..2d69bfa4da8 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -33,7 +33,7 @@ pub fn provide(providers: &mut Providers) {
 /// parameters are used).
 fn unused_generic_params<'tcx>(
     tcx: TyCtxt<'tcx>,
-    instance: ty::InstanceDef<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
 ) -> UnusedGenericParams {
     assert!(instance.def_id().is_local());
 
@@ -88,7 +88,7 @@ fn unused_generic_params<'tcx>(
 fn should_polymorphize<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    instance: ty::InstanceDef<'tcx>,
+    instance: ty::InstanceKind<'tcx>,
 ) -> bool {
     // If an instance's MIR body is not polymorphic then the modified generic parameters that are
     // derived from polymorphization's result won't make any difference.
@@ -97,7 +97,7 @@ fn should_polymorphize<'tcx>(
     }
 
     // Don't polymorphize intrinsics or virtual calls - calling `instance_mir` will panic.
-    if matches!(instance, ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::Virtual(..)) {
+    if matches!(instance, ty::InstanceKind::Intrinsic(..) | ty::InstanceKind::Virtual(..)) {
         return false;
     }
 
@@ -230,7 +230,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> {
     /// a closure, coroutine or constant).
     #[instrument(level = "debug", skip(self, def_id, args))]
     fn visit_child_body(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) {
-        let instance = ty::InstanceDef::Item(def_id);
+        let instance = ty::InstanceKind::Item(def_id);
         let unused = self.tcx.unused_generic_params(instance);
         debug!(?self.unused_parameters, ?unused);
         for (i, arg) in args.iter().enumerate() {
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index b913a05095c..144caf36ee5 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -1,3 +1,9 @@
+//! Crate containing the implementation of the next-generation trait solver.
+//!
+//! This crate may also contain things that are used by the old trait solver,
+//! but were uplifted in the process of making the new trait solver generic.
+//! So if you got to this crate from the old solver, it's totally normal.
+
 pub mod canonicalizer;
 pub mod resolve;
 pub mod solve;
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index fb57d42f6df..d3705626938 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -973,8 +973,12 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
 
 impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
-        let old_maybe_typeck_results =
-            self.maybe_typeck_results.replace(self.tcx.typeck_body(body_id));
+        let new_typeck_results = self.tcx.typeck_body(body_id);
+        // Do not try reporting privacy violations if we failed to infer types.
+        if new_typeck_results.tainted_by_errors.is_some() {
+            return;
+        }
+        let old_maybe_typeck_results = self.maybe_typeck_results.replace(new_typeck_results);
         self.visit_body(self.tcx.hir().body(body_id));
         self.maybe_typeck_results = old_maybe_typeck_results;
     }
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index b6a23317dc9..7d531385e21 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -966,7 +966,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         for single_import in &resolution.single_imports {
             let Some(import_vis) = single_import.vis.get() else {
                 // This branch handles a cycle in single imports, which occurs
-                // when we've previously captured the `vis` value during an import
+                // when we've previously **steal** the `vis` value during an import
                 // process.
                 //
                 // For example:
@@ -998,21 +998,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             let Some(module) = single_import.imported_module.get() else {
                 return Err((Undetermined, Weak::No));
             };
-            let ImportKind::Single { source: ident, target, target_bindings, .. } =
-                &single_import.kind
+            let ImportKind::Single { source, target, target_bindings, .. } = &single_import.kind
             else {
                 unreachable!();
             };
-            if (ident != target) && target_bindings.iter().all(|binding| binding.get().is_none()) {
+            if source != target {
                 // This branch allows the binding to be defined or updated later if the target name
-                // can hide the source but these bindings are not obtained.
-                // avoiding module inconsistency between the resolve process and the finalize process.
-                // See more details in #124840
-                return Err((Undetermined, Weak::No));
+                // can hide the source.
+                if target_bindings.iter().all(|binding| binding.get().is_none()) {
+                    // None of the target bindings are available, so we can't determine
+                    // if this binding is correct or not.
+                    // See more details in #124840
+                    return Err((Undetermined, Weak::No));
+                } else if target_bindings[ns].get().is_none() && binding.is_some() {
+                    // `binding.is_some()` avoids the condition where the binding
+                    // truly doesn't exist in this namespace and should return `Err(Determined)`.
+                    return Err((Undetermined, Weak::No));
+                }
             }
+
             match self.resolve_ident_in_module(
                 module,
-                *ident,
+                *source,
                 ns,
                 &single_import.parent_scope,
                 None,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index fa711d932b6..c1e83c59f98 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -310,9 +310,10 @@ enum LifetimeRibKind {
     /// error on default object bounds (e.g., `Box<dyn Foo>`).
     AnonymousReportError,
 
-    /// Resolves elided lifetimes to `'static`, but gives a warning that this behavior
-    /// is a bug and will be reverted soon.
-    AnonymousWarn(NodeId),
+    /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
+    /// otherwise give a warning that the previous behavior of introducing a new early-bound
+    /// lifetime is a bug and will be removed (if `emit_lint` is enabled).
+    StaticIfNoLifetimeInScope { lint_id: NodeId, emit_lint: bool },
 
     /// Signal we cannot find which should be the anonymous lifetime.
     ElisionFailure,
@@ -1212,7 +1213,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                             }
                             LifetimeRibKind::AnonymousCreateParameter { .. }
                             | LifetimeRibKind::AnonymousReportError
-                            | LifetimeRibKind::AnonymousWarn(_)
+                            | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
                             | LifetimeRibKind::Elided(_)
                             | LifetimeRibKind::ElisionFailure
                             | LifetimeRibKind::ConcreteAnonConst(_)
@@ -1580,7 +1581,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                                     // lifetime would be illegal.
                                     LifetimeRibKind::Item
                                     | LifetimeRibKind::AnonymousReportError
-                                    | LifetimeRibKind::AnonymousWarn(_)
+                                    | LifetimeRibKind::StaticIfNoLifetimeInScope { .. }
                                     | LifetimeRibKind::ElisionFailure => Some(LifetimeUseSet::Many),
                                     // An anonymous lifetime is legal here, and bound to the right
                                     // place, go ahead.
@@ -1643,7 +1644,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 | LifetimeRibKind::Generics { .. }
                 | LifetimeRibKind::ElisionFailure
                 | LifetimeRibKind::AnonymousReportError
-                | LifetimeRibKind::AnonymousWarn(_) => {}
+                | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {}
             }
         }
 
@@ -1677,16 +1678,36 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     self.record_lifetime_res(lifetime.id, res, elision_candidate);
                     return;
                 }
-                LifetimeRibKind::AnonymousWarn(node_id) => {
-                    self.r.lint_buffer.buffer_lint(
-                        lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
-                        node_id,
-                        lifetime.ident.span,
-                        lint::BuiltinLintDiag::AssociatedConstElidedLifetime {
-                            elided,
-                            span: lifetime.ident.span,
-                        },
-                    );
+                LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
+                    let mut lifetimes_in_scope = vec![];
+                    for rib in &self.lifetime_ribs[..i] {
+                        lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
+                        // Consider any anonymous lifetimes, too
+                        if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind
+                            && let Some(extra) = self.r.extra_lifetime_params_map.get(&binder)
+                        {
+                            lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));
+                        }
+                    }
+                    if lifetimes_in_scope.is_empty() {
+                        self.record_lifetime_res(
+                            lifetime.id,
+                            LifetimeRes::Static,
+                            elision_candidate,
+                        );
+                        return;
+                    } else if emit_lint {
+                        self.r.lint_buffer.buffer_lint(
+                            lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
+                            node_id,
+                            lifetime.ident.span,
+                            lint::BuiltinLintDiag::AssociatedConstElidedLifetime {
+                                elided,
+                                span: lifetime.ident.span,
+                                lifetimes_in_scope: lifetimes_in_scope.into(),
+                            },
+                        );
+                    }
                 }
                 LifetimeRibKind::AnonymousReportError => {
                     if elided {
@@ -1904,7 +1925,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
                     LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
-                    | LifetimeRibKind::AnonymousWarn(_) => {
+                    | LifetimeRibKind::StaticIfNoLifetimeInScope { .. } => {
                         let sess = self.r.tcx.sess;
                         let subdiag = rustc_errors::elided_lifetime_in_path_suggestion(
                             sess.source_map(),
@@ -2838,19 +2859,27 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                             kind: LifetimeBinderKind::ConstItem,
                         },
                         |this| {
-                            this.visit_generics(generics);
-                            this.visit_ty(ty);
-
-                            // Only impose the restrictions of `ConstRibKind` for an
-                            // actual constant expression in a provided default.
-                            if let Some(expr) = expr {
-                                // We allow arbitrary const expressions inside of associated consts,
-                                // even if they are potentially not const evaluatable.
-                                //
-                                // Type parameters can already be used and as associated consts are
-                                // not used as part of the type system, this is far less surprising.
-                                this.resolve_const_body(expr, None);
-                            }
+                            this.with_lifetime_rib(
+                                LifetimeRibKind::StaticIfNoLifetimeInScope {
+                                    lint_id: item.id,
+                                    emit_lint: false,
+                                },
+                                |this| {
+                                    this.visit_generics(generics);
+                                    this.visit_ty(ty);
+
+                                    // Only impose the restrictions of `ConstRibKind` for an
+                                    // actual constant expression in a provided default.
+                                    if let Some(expr) = expr {
+                                        // We allow arbitrary const expressions inside of associated consts,
+                                        // even if they are potentially not const evaluatable.
+                                        //
+                                        // Type parameters can already be used and as associated consts are
+                                        // not used as part of the type system, this is far less surprising.
+                                        this.resolve_const_body(expr, None);
+                                    }
+                                },
+                            )
                         },
                     );
                 }
@@ -3030,30 +3059,37 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         kind: LifetimeBinderKind::ConstItem,
                     },
                     |this| {
-                        this.with_lifetime_rib(LifetimeRibKind::AnonymousWarn(item.id), |this| {
-                            // If this is a trait impl, ensure the const
-                            // exists in trait
-                            this.check_trait_item(
-                                item.id,
-                                item.ident,
-                                &item.kind,
-                                ValueNS,
-                                item.span,
-                                seen_trait_items,
-                                |i, s, c| ConstNotMemberOfTrait(i, s, c),
-                            );
+                        this.with_lifetime_rib(
+                            LifetimeRibKind::StaticIfNoLifetimeInScope {
+                                lint_id: item.id,
+                                // In impls, it's not a hard error yet due to backcompat.
+                                emit_lint: true,
+                            },
+                            |this| {
+                                // If this is a trait impl, ensure the const
+                                // exists in trait
+                                this.check_trait_item(
+                                    item.id,
+                                    item.ident,
+                                    &item.kind,
+                                    ValueNS,
+                                    item.span,
+                                    seen_trait_items,
+                                    |i, s, c| ConstNotMemberOfTrait(i, s, c),
+                                );
 
-                            this.visit_generics(generics);
-                            this.visit_ty(ty);
-                            if let Some(expr) = expr {
-                                // We allow arbitrary const expressions inside of associated consts,
-                                // even if they are potentially not const evaluatable.
-                                //
-                                // Type parameters can already be used and as associated consts are
-                                // not used as part of the type system, this is far less surprising.
-                                this.resolve_const_body(expr, None);
-                            }
-                        });
+                                this.visit_generics(generics);
+                                this.visit_ty(ty);
+                                if let Some(expr) = expr {
+                                    // We allow arbitrary const expressions inside of associated consts,
+                                    // even if they are potentially not const evaluatable.
+                                    //
+                                    // Type parameters can already be used and as associated consts are
+                                    // not used as part of the type system, this is far less surprising.
+                                    this.resolve_const_body(expr, None);
+                                }
+                            },
+                        );
                     },
                 );
             }
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 2cb0c06e336..832efb11999 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -288,9 +288,9 @@ pub fn transform_instance<'tcx>(
     mut instance: Instance<'tcx>,
     options: TransformTyOptions,
 ) -> Instance<'tcx> {
-    if (matches!(instance.def, ty::InstanceDef::Virtual(..))
+    if (matches!(instance.def, ty::InstanceKind::Virtual(..))
         && tcx.is_lang_item(instance.def_id(), LangItem::DropInPlace))
-        || matches!(instance.def, ty::InstanceDef::DropGlue(..))
+        || matches!(instance.def, ty::InstanceKind::DropGlue(..))
     {
         // Adjust the type ids of DropGlues
         //
@@ -316,7 +316,7 @@ pub fn transform_instance<'tcx>(
         let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
         let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
         instance.args = tcx.mk_args_trait(self_ty, List::empty());
-    } else if let ty::InstanceDef::Virtual(def_id, _) = instance.def {
+    } else if let ty::InstanceKind::Virtual(def_id, _) = instance.def {
         // Transform self into a trait object of the trait that defines the method for virtual
         // functions to match the type erasure done below.
         let upcast_ty = match tcx.trait_of_item(def_id) {
@@ -343,7 +343,7 @@ pub fn transform_instance<'tcx>(
             tcx.types.unit
         };
         instance.args = tcx.mk_args_trait(self_ty, instance.args.into_iter().skip(1));
-    } else if let ty::InstanceDef::VTableShim(def_id) = instance.def
+    } else if let ty::InstanceKind::VTableShim(def_id) = instance.def
         && let Some(trait_id) = tcx.trait_of_item(def_id)
     {
         // Adjust the type ids of VTableShims to the type id expected in the call sites for the
@@ -387,7 +387,7 @@ pub fn transform_instance<'tcx>(
                 // If we ever *do* start encoding the vtable index, we will need to generate an alias set
                 // based on which vtables we are putting this method into, as there will be more than one
                 // index value when supertraits are involved.
-                instance.def = ty::InstanceDef::Virtual(method_id, 0);
+                instance.def = ty::InstanceKind::Virtual(method_id, 0);
                 let abstract_trait_args =
                     tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
                 instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
@@ -442,7 +442,7 @@ pub fn transform_instance<'tcx>(
                 .expect("No call-family function on closure-like Fn trait?")
                 .def_id;
 
-            instance.def = ty::InstanceDef::Virtual(call, 0);
+            instance.def = ty::InstanceKind::Virtual(call, 0);
             instance.args = abstract_args;
         }
     }
diff --git a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs
index 436c398e39b..651ba612469 100644
--- a/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs
+++ b/compiler/rustc_sanitizers/src/kcfi/typeid/mod.rs
@@ -3,7 +3,7 @@
 //!
 //! For more information about LLVM KCFI and cross-language LLVM KCFI support for the Rust compiler,
 //! see the tracking issue #123479.
-use rustc_middle::ty::{Instance, InstanceDef, ReifyReason, Ty, TyCtxt};
+use rustc_middle::ty::{Instance, InstanceKind, ReifyReason, Ty, TyCtxt};
 use rustc_target::abi::call::FnAbi;
 use std::hash::Hasher;
 use twox_hash::XxHash64;
@@ -44,7 +44,7 @@ pub fn typeid_for_instance<'tcx>(
     //
     // This was implemented for KCFI support in #123106 and #123052 (which introduced the
     // ReifyReason). The tracking issue for KCFI support for Rust is #123479.
-    if matches!(instance.def, InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr))) {
+    if matches!(instance.def, InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr))) {
         options.insert(TypeIdOptions::USE_CONCRETE_SELF);
     }
     // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs
index 577373cbc95..42fa6989ddc 100644
--- a/compiler/rustc_smir/src/rustc_smir/builder.rs
+++ b/compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -19,7 +19,7 @@ impl<'tcx> BodyBuilder<'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
         let instance = match instance.def {
             // To get the fallback body of an intrinsic, we need to convert it to an item.
-            ty::InstanceDef::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
+            ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
             _ => instance,
         };
         BodyBuilder { tcx, instance }
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 4348bc31bf9..9afd507ce11 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -60,7 +60,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
         let mut tables = self.0.borrow_mut();
         let def_id = tables[item];
-        tables.tcx.instance_mir(rustc_middle::ty::InstanceDef::Item(def_id)).stable(&mut tables)
+        tables.tcx.instance_mir(rustc_middle::ty::InstanceKind::Item(def_id)).stable(&mut tables)
     }
 
     fn has_body(&self, def: DefId) -> bool {
@@ -548,13 +548,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
     fn is_empty_drop_shim(&self, def: InstanceDef) -> bool {
         let tables = self.0.borrow_mut();
         let instance = tables.instances[def];
-        matches!(instance.def, ty::InstanceDef::DropGlue(_, None))
+        matches!(instance.def, ty::InstanceKind::DropGlue(_, None))
     }
 
     fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool {
         let tables = self.0.borrow_mut();
         let instance = tables.instances[def];
-        matches!(instance.def, ty::InstanceDef::AsyncDropGlueCtorShim(_, None))
+        matches!(instance.def, ty::InstanceKind::AsyncDropGlueCtorShim(_, None))
     }
 
     fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index e3cd7187e77..9cd841bba10 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -839,22 +839,22 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         let def = tables.instance_def(tables.tcx.lift(*self).unwrap());
         let kind = match self.def {
-            ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
-            ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
-            ty::InstanceDef::Virtual(_def_id, idx) => {
+            ty::InstanceKind::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
+            ty::InstanceKind::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
+            ty::InstanceKind::Virtual(_def_id, idx) => {
                 stable_mir::mir::mono::InstanceKind::Virtual { idx }
             }
-            ty::InstanceDef::VTableShim(..)
-            | ty::InstanceDef::ReifyShim(..)
-            | ty::InstanceDef::FnPtrAddrShim(..)
-            | ty::InstanceDef::ClosureOnceShim { .. }
-            | ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-            | ty::InstanceDef::CoroutineKindShim { .. }
-            | ty::InstanceDef::ThreadLocalShim(..)
-            | ty::InstanceDef::DropGlue(..)
-            | ty::InstanceDef::CloneShim(..)
-            | ty::InstanceDef::FnPtrShim(..)
-            | ty::InstanceDef::AsyncDropGlueCtorShim(..) => {
+            ty::InstanceKind::VTableShim(..)
+            | ty::InstanceKind::ReifyShim(..)
+            | ty::InstanceKind::FnPtrAddrShim(..)
+            | ty::InstanceKind::ClosureOnceShim { .. }
+            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+            | ty::InstanceKind::CoroutineKindShim { .. }
+            | ty::InstanceKind::ThreadLocalShim(..)
+            | ty::InstanceKind::DropGlue(..)
+            | ty::InstanceKind::CloneShim(..)
+            | ty::InstanceKind::FnPtrShim(..)
+            | ty::InstanceKind::AsyncDropGlueCtorShim(..) => {
                 stable_mir::mir::mono::InstanceKind::Shim
             }
         };
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 89f9adfcfd6..82522e995d6 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -60,9 +60,9 @@ impl<'tcx> Tables<'tcx> {
         self.item_has_body(def_id)
             || !matches!(
                 instance.def,
-                ty::InstanceDef::Virtual(..)
-                    | ty::InstanceDef::Intrinsic(..)
-                    | ty::InstanceDef::Item(..)
+                ty::InstanceKind::Virtual(..)
+                    | ty::InstanceKind::Intrinsic(..)
+                    | ty::InstanceKind::Item(..)
             )
     }
 
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 75cac6c7992..9edd2ff9b1a 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -56,8 +56,8 @@ pub(super) fn mangle<'tcx>(
     printer
         .print_def_path(
             def_id,
-            if let ty::InstanceDef::DropGlue(_, _) | ty::InstanceDef::AsyncDropGlueCtorShim(_, _) =
-                instance.def
+            if let ty::InstanceKind::DropGlue(_, _)
+            | ty::InstanceKind::AsyncDropGlueCtorShim(_, _) = instance.def
             {
                 // Add the name of the dropped type to the symbol name
                 &*instance.args
@@ -68,13 +68,13 @@ pub(super) fn mangle<'tcx>(
         .unwrap();
 
     match instance.def {
-        ty::InstanceDef::ThreadLocalShim(..) => {
+        ty::InstanceKind::ThreadLocalShim(..) => {
             printer.write_str("{{tls-shim}}").unwrap();
         }
-        ty::InstanceDef::VTableShim(..) => {
+        ty::InstanceKind::VTableShim(..) => {
             printer.write_str("{{vtable-shim}}").unwrap();
         }
-        ty::InstanceDef::ReifyShim(_, reason) => {
+        ty::InstanceKind::ReifyShim(_, reason) => {
             printer.write_str("{{reify-shim").unwrap();
             match reason {
                 Some(ReifyReason::FnPtr) => printer.write_str("-fnptr").unwrap(),
@@ -85,8 +85,8 @@ pub(super) fn mangle<'tcx>(
         }
         // FIXME(async_closures): This shouldn't be needed when we fix
         // `Instance::ty`/`Instance::def_id`.
-        ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-        | ty::InstanceDef::CoroutineKindShim { .. } => {
+        ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+        | ty::InstanceKind::CoroutineKindShim { .. } => {
             printer.write_str("{{fn-once-shim}}").unwrap();
         }
         _ => {}
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 55479bce6fc..42c4fa83d1b 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -43,14 +43,14 @@ pub(super) fn mangle<'tcx>(
 
     // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance.
     let shim_kind = match instance.def {
-        ty::InstanceDef::ThreadLocalShim(_) => Some("tls"),
-        ty::InstanceDef::VTableShim(_) => Some("vtable"),
-        ty::InstanceDef::ReifyShim(_, None) => Some("reify"),
-        ty::InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"),
-        ty::InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"),
-
-        ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
-        | ty::InstanceDef::CoroutineKindShim { .. } => Some("fn_once"),
+        ty::InstanceKind::ThreadLocalShim(_) => Some("tls"),
+        ty::InstanceKind::VTableShim(_) => Some("vtable"),
+        ty::InstanceKind::ReifyShim(_, None) => Some("reify"),
+        ty::InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"),
+        ty::InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"),
+
+        ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
+        | ty::InstanceKind::CoroutineKindShim { .. } => Some("fn_once"),
 
         _ => None,
     };
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 0e0b9e98339..b5753d60f59 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -135,8 +135,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         // Remove any trivial region constraints once we've resolved regions
         external_constraints
             .region_constraints
-            .outlives
-            .retain(|(outlives, _)| outlives.0.as_region().map_or(true, |re| re != outlives.1));
+            .retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1));
 
         let canonical = Canonicalizer::canonicalize(
             self.infcx,
@@ -179,8 +178,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
     fn compute_external_query_constraints(
         &self,
         certainty: Certainty,
-        normalization_nested_goals: NestedNormalizationGoals<'tcx>,
-    ) -> ExternalConstraintsData<'tcx> {
+        normalization_nested_goals: NestedNormalizationGoals<TyCtxt<'tcx>>,
+    ) -> ExternalConstraintsData<TyCtxt<'tcx>> {
         // We only return region constraints once the certainty is `Yes`. This
         // is necessary as we may drop nested goals on ambiguity, which may result
         // in unconstrained inference variables in the region constraints. It also
@@ -193,30 +192,40 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
             // Cannot use `take_registered_region_obligations` as we may compute the response
             // inside of a `probe` whenever we have multiple choices inside of the solver.
             let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
-            let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| {
-                make_query_region_constraints(
-                    self.interner(),
-                    region_obligations.iter().map(|r_o| {
-                        (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
-                    }),
-                    region_constraints,
-                )
-            });
-
+            let QueryRegionConstraints { outlives, member_constraints } =
+                self.infcx.with_region_constraints(|region_constraints| {
+                    make_query_region_constraints(
+                        self.interner(),
+                        region_obligations.iter().map(|r_o| {
+                            (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
+                        }),
+                        region_constraints,
+                    )
+                });
+            assert_eq!(member_constraints, vec![]);
             let mut seen = FxHashSet::default();
-            region_constraints.outlives.retain(|outlives| seen.insert(*outlives));
-            region_constraints
+            outlives
+                .into_iter()
+                .filter(|(outlives, _)| seen.insert(*outlives))
+                .map(|(outlives, _origin)| outlives)
+                .collect()
         } else {
             Default::default()
         };
 
-        let mut opaque_types = self.infcx.clone_opaque_types_for_query_response();
-        // Only return opaque type keys for newly-defined opaques
-        opaque_types.retain(|(a, _)| {
-            self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
-        });
-
-        ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
+        ExternalConstraintsData {
+            region_constraints,
+            opaque_types: self
+                .infcx
+                .clone_opaque_types_for_query_response()
+                .into_iter()
+                // Only return *newly defined* opaque types.
+                .filter(|(a, _)| {
+                    self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
+                })
+                .collect(),
+            normalization_nested_goals,
+        }
     }
 
     /// After calling a canonical query, we apply the constraints returned
@@ -232,7 +241,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         param_env: ty::ParamEnv<'tcx>,
         original_values: Vec<ty::GenericArg<'tcx>>,
         response: CanonicalResponse<'tcx>,
-    ) -> (NestedNormalizationGoals<'tcx>, Certainty) {
+    ) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty) {
         let instantiation = Self::compute_query_response_instantiation_values(
             self.infcx,
             &original_values,
@@ -369,16 +378,17 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         }
     }
 
-    fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) {
-        for &(ty::OutlivesPredicate(lhs, rhs), _) in &region_constraints.outlives {
+    fn register_region_constraints(
+        &mut self,
+        outlives: &[ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>],
+    ) {
+        for &ty::OutlivesPredicate(lhs, rhs) in outlives {
             match lhs.unpack() {
                 GenericArgKind::Lifetime(lhs) => self.register_region_outlives(lhs, rhs),
                 GenericArgKind::Type(lhs) => self.register_ty_outlives(lhs, rhs),
                 GenericArgKind::Const(_) => bug!("const outlives: {lhs:?}: {rhs:?}"),
             }
         }
-
-        assert!(region_constraints.member_constraints.is_empty());
     }
 
     fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)]) {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 6b8375b53e8..74938d2bbd7 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -29,11 +29,9 @@ use super::inspect::ProofTreeBuilder;
 use super::{search_graph, GoalEvaluationKind, FIXPOINT_STEP_LIMIT};
 use super::{search_graph::SearchGraph, Goal};
 use super::{GoalSource, SolverMode};
-pub use select::InferCtxtSelectExt;
 
 pub(super) mod canonical;
 mod probe;
-mod select;
 
 pub struct EvalCtxt<'a, Infcx, I = <Infcx as InferCtxtLike>::Interner>
 where
@@ -339,7 +337,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
         goal_evaluation_kind: GoalEvaluationKind,
         _source: GoalSource,
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
-    ) -> Result<(NestedNormalizationGoals<'tcx>, bool, Certainty), NoSolution> {
+    ) -> Result<(NestedNormalizationGoals<TyCtxt<'tcx>>, bool, Certainty), NoSolution> {
         let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
         let mut goal_evaluation =
             self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
@@ -382,7 +380,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
         param_env: ty::ParamEnv<'tcx>,
         original_values: Vec<ty::GenericArg<'tcx>>,
         response: CanonicalResponse<'tcx>,
-    ) -> (NestedNormalizationGoals<'tcx>, Certainty, bool) {
+    ) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty, bool) {
         if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty {
             return (NestedNormalizationGoals::empty(), response.value.certainty, false);
         }
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index fdcf4ff11e4..4f1be5cbc85 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -37,12 +37,14 @@ mod normalize;
 mod normalizes_to;
 mod project_goals;
 mod search_graph;
+mod select;
 mod trait_goals;
 
-pub use eval_ctxt::{EvalCtxt, GenerateProofTree, InferCtxtEvalExt, InferCtxtSelectExt};
+pub use eval_ctxt::{EvalCtxt, GenerateProofTree, InferCtxtEvalExt};
 pub use fulfill::{FulfillmentCtxt, NextSolverError};
 pub(crate) use normalize::deeply_normalize_for_diagnostics;
 pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes};
+pub use select::InferCtxtSelectExt;
 
 /// How many fixpoint iterations we should attempt inside of the solver before bailing
 /// with overflow.
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 60a15392e0b..5c5923e9d39 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -10,13 +10,13 @@ use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::solve::inspect::ProbeKind;
 use rustc_infer::traits::solve::MaybeCause;
 use rustc_infer::traits::Reveal;
+use rustc_middle::bug;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::NormalizesTo;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{TypeVisitableExt, Upcast};
-use rustc_middle::{bug, span_bug};
 use rustc_span::{ErrorGuaranteed, DUMMY_SP};
 
 mod anon_const;
@@ -200,14 +200,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
             let error_response = |ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, reason| {
                 let guar = tcx.dcx().span_delayed_bug(tcx.def_span(assoc_def.item.def_id), reason);
-                let error_term = match assoc_def.item.kind {
-                    ty::AssocKind::Const => ty::Const::new_error(tcx, guar).into(),
-                    ty::AssocKind::Type => Ty::new_error(tcx, guar).into(),
-                    // This makes no sense...
-                    ty::AssocKind::Fn => span_bug!(
-                        tcx.def_span(assoc_def.item.def_id),
-                        "cannot project to an associated function"
-                    ),
+                let error_term = match goal.predicate.alias.kind(tcx) {
+                    ty::AliasTermKind::ProjectionTy => Ty::new_error(tcx, guar).into(),
+                    ty::AliasTermKind::ProjectionConst => ty::Const::new_error(tcx, guar).into(),
+                    kind => bug!("expected projection, found {kind:?}"),
                 };
                 ecx.instantiate_normalizes_to_term(goal, error_term);
                 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
@@ -238,9 +234,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             }
 
             // Finally we construct the actual value of the associated type.
-            let term = match assoc_def.item.kind {
-                ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()),
-                ty::AssocKind::Const => {
+            let term = match goal.predicate.alias.kind(tcx) {
+                ty::AliasTermKind::ProjectionTy => {
+                    tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into())
+                }
+                ty::AliasTermKind::ProjectionConst => {
                     if tcx.features().associated_const_equality {
                         bug!("associated const projection is not supported yet")
                     } else {
@@ -254,7 +252,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                         )
                     }
                 }
-                ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
+                kind => bug!("expected projection, found {kind:?}"),
             };
 
             ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, associated_item_args));
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs
index 257fd263b94..257fd263b94 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/select.rs
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index c5ea85c90dc..f1dd94839fe 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -5,7 +5,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{
     fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout,
 };
-use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt};
 use rustc_session::config::OptLevel;
 use rustc_span::def_id::DefId;
 use rustc_target::abi::call::{
@@ -33,7 +33,7 @@ fn fn_sig_for_fn_abi<'tcx>(
     instance: ty::Instance<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 ) -> ty::PolyFnSig<'tcx> {
-    if let InstanceDef::ThreadLocalShim(..) = instance.def {
+    if let InstanceKind::ThreadLocalShim(..) = instance.def {
         return ty::Binder::dummy(tcx.mk_fn_sig(
             [],
             tcx.thread_local_ptr_ty(instance.def_id()),
@@ -63,7 +63,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 _ => unreachable!(),
             };
 
-            if let ty::InstanceDef::VTableShim(..) = instance.def {
+            if let ty::InstanceKind::VTableShim(..) = instance.def {
                 // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
                 sig = sig.map_bound(|mut sig| {
                     let mut inputs_and_output = sig.inputs_and_output.to_vec();
@@ -121,7 +121,7 @@ fn fn_sig_for_fn_abi<'tcx>(
             let mut coroutine_kind = args.as_coroutine_closure().kind();
 
             let env_ty =
-                if let InstanceDef::ConstructCoroutineInClosureShim { receiver_by_ref, .. } =
+                if let InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } =
                     instance.def
                 {
                     coroutine_kind = ty::ClosureKind::FnOnce;
@@ -174,7 +174,7 @@ fn fn_sig_for_fn_abi<'tcx>(
             // make sure we respect the `target_kind` in that shim.
             // FIXME(async_closures): This shouldn't be needed, and we should be populating
             // a separate def-id for these bodies.
-            if let InstanceDef::CoroutineKindShim { .. } = instance.def {
+            if let InstanceKind::CoroutineKindShim { .. } = instance.def {
                 // Grab the parent coroutine-closure. It has the same args for the purposes
                 // of instantiation, so this will be okay to do.
                 let ty::CoroutineClosure(_, coroutine_closure_args) = *tcx
@@ -386,7 +386,7 @@ fn fn_abi_of_instance<'tcx>(
         extra_args,
         caller_location,
         Some(instance.def_id()),
-        matches!(instance.def, ty::InstanceDef::Virtual(..)),
+        matches!(instance.def, ty::InstanceKind::Virtual(..)),
     )
 }
 
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index fcd808b5946..c50a490a9dc 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -34,7 +34,7 @@ fn resolve_instance<'tcx>(
     } else {
         let def = if tcx.intrinsic(def_id).is_some() {
             debug!(" => intrinsic");
-            ty::InstanceDef::Intrinsic(def_id)
+            ty::InstanceKind::Intrinsic(def_id)
         } else if tcx.is_lang_item(def_id, LangItem::DropInPlace) {
             let ty = args.type_at(0);
 
@@ -53,10 +53,10 @@ fn resolve_instance<'tcx>(
                     _ => return Ok(None),
                 }
 
-                ty::InstanceDef::DropGlue(def_id, Some(ty))
+                ty::InstanceKind::DropGlue(def_id, Some(ty))
             } else {
                 debug!(" => trivial drop glue");
-                ty::InstanceDef::DropGlue(def_id, None)
+                ty::InstanceKind::DropGlue(def_id, None)
             }
         } else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) {
             let ty = args.type_at(0);
@@ -75,15 +75,15 @@ fn resolve_instance<'tcx>(
                     _ => return Ok(None),
                 }
                 debug!(" => nontrivial async drop glue ctor");
-                ty::InstanceDef::AsyncDropGlueCtorShim(def_id, Some(ty))
+                ty::InstanceKind::AsyncDropGlueCtorShim(def_id, Some(ty))
             } else {
                 debug!(" => trivial async drop glue ctor");
-                ty::InstanceDef::AsyncDropGlueCtorShim(def_id, None)
+                ty::InstanceKind::AsyncDropGlueCtorShim(def_id, None)
             }
         } else {
             debug!(" => free item");
             // FIXME(effects): we may want to erase the effect param if that is present on this item.
-            ty::InstanceDef::Item(def_id)
+            ty::InstanceKind::Item(def_id)
         };
 
         Ok(Some(Instance { def, args }))
@@ -226,7 +226,7 @@ fn resolve_associated_item<'tcx>(
                     .copied()
                     .position(|def_id| def_id == trait_item_id);
                 offset.map(|offset| Instance {
-                    def: ty::InstanceDef::Virtual(trait_item_id, vtable_base + offset),
+                    def: ty::InstanceKind::Virtual(trait_item_id, vtable_base + offset),
                     args: rcvr_args,
                 })
             }
@@ -248,7 +248,7 @@ fn resolve_associated_item<'tcx>(
                     };
 
                     Some(Instance {
-                        def: ty::InstanceDef::CloneShim(trait_item_id, self_ty),
+                        def: ty::InstanceKind::CloneShim(trait_item_id, self_ty),
                         args: rcvr_args,
                     })
                 } else {
@@ -265,7 +265,7 @@ fn resolve_associated_item<'tcx>(
                         return Ok(None);
                     }
                     Some(Instance {
-                        def: ty::InstanceDef::FnPtrAddrShim(trait_item_id, self_ty),
+                        def: ty::InstanceKind::FnPtrAddrShim(trait_item_id, self_ty),
                         args: rcvr_args,
                     })
                 } else {
@@ -283,7 +283,7 @@ fn resolve_associated_item<'tcx>(
                 {
                     // For compiler developers who'd like to add new items to `Fn`/`FnMut`/`FnOnce`,
                     // you either need to generate a shim body, or perhaps return
-                    // `InstanceDef::Item` pointing to a trait default method body if
+                    // `InstanceKind::Item` pointing to a trait default method body if
                     // it is given a default implementation by the trait.
                     bug!(
                         "no definition for `{trait_ref}::{}` for built-in callable type",
@@ -295,7 +295,7 @@ fn resolve_associated_item<'tcx>(
                         Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind))
                     }
                     ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
-                        def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_args.type_at(0)),
+                        def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)),
                         args: rcvr_args,
                     }),
                     ty::CoroutineClosure(coroutine_closure_def_id, args) => {
@@ -308,7 +308,7 @@ fn resolve_associated_item<'tcx>(
                             Some(Instance::new(coroutine_closure_def_id, args))
                         } else {
                             Some(Instance {
-                                def: ty::InstanceDef::ConstructCoroutineInClosureShim {
+                                def: ty::InstanceKind::ConstructCoroutineInClosureShim {
                                     coroutine_closure_def_id,
                                     receiver_by_ref: target_kind != ty::ClosureKind::FnOnce,
                                 },
@@ -331,7 +331,7 @@ fn resolve_associated_item<'tcx>(
                             // If we're computing `AsyncFnOnce` for a by-ref closure then
                             // construct a new body that has the right return types.
                             Some(Instance {
-                                def: ty::InstanceDef::ConstructCoroutineInClosureShim {
+                                def: ty::InstanceKind::ConstructCoroutineInClosureShim {
                                     coroutine_closure_def_id,
                                     receiver_by_ref: false,
                                 },
@@ -345,7 +345,7 @@ fn resolve_associated_item<'tcx>(
                         Some(Instance::resolve_closure(tcx, closure_def_id, args, target_kind))
                     }
                     ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
-                        def: ty::InstanceDef::FnPtrShim(trait_item_id, rcvr_args.type_at(0)),
+                        def: ty::InstanceKind::FnPtrShim(trait_item_id, rcvr_args.type_at(0)),
                         args: rcvr_args,
                     }),
                     _ => bug!(
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index a2b71e1fc25..11c1f73fef3 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -29,6 +29,7 @@ pub trait Interner:
     + IrPrint<ty::FnSig<Self>>
 {
     type DefId: Copy + Debug + Hash + Eq + TypeFoldable<Self>;
+    type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
     type AdtDef: AdtDef<Self>;
 
     type GenericArgs: GenericArgs<Self>;
@@ -103,7 +104,11 @@ pub trait Interner:
     type GenericsOf: GenericsOf<Self>;
     fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
 
-    type VariancesOf: Copy + Debug + Deref<Target = [ty::Variance]>;
+    type VariancesOf: Copy
+        + Debug
+        + Deref<Target = [ty::Variance]>
+        // FIXME: This is terrible!
+        + IntoIterator<Item: Deref<Target = ty::Variance>>;
     fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
 
     // FIXME: Remove after uplifting `EarlyBinder`
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 4775a0f8cbb..ac9b2808804 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -47,6 +47,7 @@ mod flags;
 mod generic_arg;
 mod infcx;
 mod interner;
+mod opaque_ty;
 mod predicate;
 mod predicate_kind;
 mod region_kind;
@@ -63,6 +64,7 @@ pub use flags::*;
 pub use generic_arg::*;
 pub use infcx::InferCtxtLike;
 pub use interner::*;
+pub use opaque_ty::*;
 pub use predicate::*;
 pub use predicate_kind::*;
 pub use region_kind::*;
diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs
new file mode 100644
index 00000000000..60737066597
--- /dev/null
+++ b/compiler/rustc_type_ir/src/opaque_ty.rs
@@ -0,0 +1,51 @@
+use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
+use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
+
+use crate::inherent::*;
+use crate::{self as ty, Interner};
+
+#[derive(derivative::Derivative)]
+#[derivative(
+    Clone(bound = ""),
+    Hash(bound = ""),
+    PartialEq(bound = ""),
+    Eq(bound = ""),
+    Debug(bound = ""),
+    Copy(bound = "")
+)]
+#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
+#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
+pub struct OpaqueTypeKey<I: Interner> {
+    pub def_id: I::LocalDefId,
+    pub args: I::GenericArgs,
+}
+
+impl<I: Interner> OpaqueTypeKey<I> {
+    pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> {
+        let variances = tcx.variances_of(self.def_id.into());
+        std::iter::zip(self.args, variances.into_iter()).enumerate().filter_map(|(i, (arg, v))| {
+            match (arg.kind(), *v) {
+                (_, ty::Invariant) => Some((i, arg)),
+                (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
+                _ => panic!("unexpected opaque type arg variance"),
+            }
+        })
+    }
+
+    pub fn fold_captured_lifetime_args(
+        self,
+        tcx: I,
+        mut f: impl FnMut(I::Region) -> I::Region,
+    ) -> Self {
+        let Self { def_id, args } = self;
+        let variances = tcx.variances_of(def_id.into());
+        let args =
+            std::iter::zip(args, variances.into_iter()).map(|(arg, v)| match (arg.kind(), *v) {
+                (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
+                (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
+                _ => arg,
+            });
+        let args = tcx.mk_args_from_iter(args);
+        Self { def_id, args }
+    }
+}
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs
index 37c9532ad89..7abcc370c88 100644
--- a/compiler/rustc_type_ir/src/region_kind.rs
+++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -154,7 +154,7 @@ pub enum RegionKind<I: Interner> {
     /// parameters via `tcx.liberate_late_bound_regions`. They are then treated
     /// the same way as `ReEarlyParam` while inside of the function.
     ///
-    /// See <https://rustc-dev-guide.rust-lang.org/early-late-bound-summary.html> for
+    /// See <https://rustc-dev-guide.rust-lang.org/early-late-bound-params/early-late-bound-summary.html> for
     /// more info about early and late bound lifetime parameters.
     ReLateParam(I::LateParamRegion),
 
diff --git a/compiler/rustc_type_ir/src/solve.rs b/compiler/rustc_type_ir/src/solve.rs
index 6a89a8a4cc3..99d2fa74494 100644
--- a/compiler/rustc_type_ir/src/solve.rs
+++ b/compiler/rustc_type_ir/src/solve.rs
@@ -7,7 +7,55 @@ use std::hash::Hash;
 use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
 use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
 
-use crate::{Canonical, CanonicalVarValues, Interner, Upcast};
+use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
+
+/// Depending on the stage of compilation, we want projection to be
+/// more or less conservative.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
+pub enum Reveal {
+    /// At type-checking time, we refuse to project any associated
+    /// type that is marked `default`. Non-`default` ("final") types
+    /// are always projected. This is necessary in general for
+    /// soundness of specialization. However, we *could* allow
+    /// projections in fully-monomorphic cases. We choose not to,
+    /// because we prefer for `default type` to force the type
+    /// definition to be treated abstractly by any consumers of the
+    /// impl. Concretely, that means that the following example will
+    /// fail to compile:
+    ///
+    /// ```compile_fail,E0308
+    /// #![feature(specialization)]
+    /// trait Assoc {
+    ///     type Output;
+    /// }
+    ///
+    /// impl<T> Assoc for T {
+    ///     default type Output = bool;
+    /// }
+    ///
+    /// fn main() {
+    ///     let x: <() as Assoc>::Output = true;
+    /// }
+    /// ```
+    ///
+    /// We also do not reveal the hidden type of opaque types during
+    /// type-checking.
+    UserFacing,
+
+    /// At codegen time, all monomorphic projections will succeed.
+    /// Also, `impl Trait` is normalized to the concrete type,
+    /// which has to be already collected by type-checking.
+    ///
+    /// NOTE: as `impl Trait`'s concrete type should *never*
+    /// be observable directly by the user, `Reveal::All`
+    /// should not be used by checks which may expose
+    /// type equality or type contents to the user.
+    /// There are some exceptions, e.g., around auto traits and
+    /// transmute-checking, which expose some details, but
+    /// not the whole concrete type of the `impl Trait`.
+    All,
+}
 
 pub type CanonicalInput<I, T = <I as Interner>::Predicate> = Canonical<I, QueryInput<I, T>>;
 pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
@@ -206,6 +254,47 @@ pub struct Response<I: Interner> {
     pub external_constraints: I::ExternalConstraints,
 }
 
+/// Additional constraints returned on success.
+#[derive(derivative::Derivative)]
+#[derivative(
+    Clone(bound = ""),
+    Hash(bound = ""),
+    PartialEq(bound = ""),
+    Eq(bound = ""),
+    Debug(bound = ""),
+    Default(bound = "")
+)]
+#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
+#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
+pub struct ExternalConstraintsData<I: Interner> {
+    pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>,
+    pub opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
+    pub normalization_nested_goals: NestedNormalizationGoals<I>,
+}
+
+#[derive(derivative::Derivative)]
+#[derivative(
+    Clone(bound = ""),
+    Hash(bound = ""),
+    PartialEq(bound = ""),
+    Eq(bound = ""),
+    Debug(bound = ""),
+    Default(bound = "")
+)]
+#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
+#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
+pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
+
+impl<I: Interner> NestedNormalizationGoals<I> {
+    pub fn empty() -> Self {
+        NestedNormalizationGoals(vec![])
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.0.is_empty()
+    }
+}
+
 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
 pub enum Certainty {
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 042a8c9925f..150e4f3f318 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -928,7 +928,7 @@ pub(crate) mod tags {
 /// An `Option` with a type tag `I`.
 ///
 /// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
-/// option. The type can be checked dynamically using `Erased::tag_id` and since this is statically
+/// option. The type can be checked dynamically using `Tagged::tag_id` and since this is statically
 /// checked for the concrete type, there is some degree of type safety.
 #[repr(transparent)]
 pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);
diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs
index 5c3a0a98b10..63193bbfb35 100644
--- a/library/core/src/future/async_drop.rs
+++ b/library/core/src/future/async_drop.rs
@@ -1,4 +1,4 @@
-#![unstable(feature = "async_drop", issue = "none")]
+#![unstable(feature = "async_drop", issue = "126482")]
 
 use crate::fmt;
 use crate::future::{Future, IntoFuture};
@@ -10,27 +10,27 @@ use crate::task::{ready, Context, Poll};
 
 /// Asynchronously drops a value by running `AsyncDrop::async_drop`
 /// on a value and its fields recursively.
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 pub fn async_drop<T>(value: T) -> AsyncDropOwning<T> {
     AsyncDropOwning { value: MaybeUninit::new(value), dtor: None, _pinned: PhantomPinned }
 }
 
 /// A future returned by the [`async_drop`].
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 pub struct AsyncDropOwning<T> {
     value: MaybeUninit<T>,
     dtor: Option<AsyncDropInPlace<T>>,
     _pinned: PhantomPinned,
 }
 
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 impl<T> fmt::Debug for AsyncDropOwning<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("AsyncDropOwning").finish_non_exhaustive()
     }
 }
 
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 impl<T> Future for AsyncDropOwning<T> {
     type Output = ();
 
@@ -86,24 +86,24 @@ unsafe fn async_drop_in_place_raw<T: ?Sized>(
 ///   returned future stores the `to_drop` pointer and user is required
 ///   to guarantee that dropped value doesn't move.
 ///
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 pub unsafe fn async_drop_in_place<T: ?Sized>(to_drop: *mut T) -> AsyncDropInPlace<T> {
     // SAFETY: `async_drop_in_place_raw` has the same safety requirements
     unsafe { AsyncDropInPlace(async_drop_in_place_raw(to_drop)) }
 }
 
 /// A future returned by the [`async_drop_in_place`].
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 pub struct AsyncDropInPlace<T: ?Sized>(<T as AsyncDestruct>::AsyncDestructor);
 
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 impl<T: ?Sized> fmt::Debug for AsyncDropInPlace<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("AsyncDropInPlace").finish_non_exhaustive()
     }
 }
 
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 impl<T: ?Sized> Future for AsyncDropInPlace<T> {
     type Output = ();
 
@@ -117,18 +117,18 @@ impl<T: ?Sized> Future for AsyncDropInPlace<T> {
 // FIXME(zetanumbers): Add same restrictions on AsyncDrop impls as
 //   with Drop impls
 /// Custom code within the asynchronous destructor.
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 #[lang = "async_drop"]
 pub trait AsyncDrop {
     /// A future returned by the [`AsyncDrop::async_drop`] to be part
     /// of the async destructor.
-    #[unstable(feature = "async_drop", issue = "none")]
+    #[unstable(feature = "async_drop", issue = "126482")]
     type Dropper<'a>: Future<Output = ()>
     where
         Self: 'a;
 
     /// Constructs the asynchronous destructor for this type.
-    #[unstable(feature = "async_drop", issue = "none")]
+    #[unstable(feature = "async_drop", issue = "126482")]
     fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_>;
 }
 
diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs
index 873cccc7e96..3a1451abfa4 100644
--- a/library/core/src/future/mod.rs
+++ b/library/core/src/future/mod.rs
@@ -37,7 +37,7 @@ pub use ready::{ready, Ready};
 #[stable(feature = "future_poll_fn", since = "1.64.0")]
 pub use poll_fn::{poll_fn, PollFn};
 
-#[unstable(feature = "async_drop", issue = "none")]
+#[unstable(feature = "async_drop", issue = "126482")]
 pub use async_drop::{async_drop, async_drop_in_place, AsyncDrop, AsyncDropInPlace};
 
 /// This type is needed because:
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 55bb6166f10..44889484963 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2784,8 +2784,10 @@ macro_rules! int_impl {
         ///
         /// In other words, the result is `self / rhs` rounded to the integer `q`
         /// such that `self >= q * rhs`.
-        /// If `self > 0`, this is equal to round towards zero (the default in Rust);
-        /// if `self < 0`, this is equal to round towards +/- infinity.
+        /// If `self > 0`, this is equal to rounding towards zero (the default in Rust);
+        /// if `self < 0`, this is equal to rounding away from zero (towards +/- infinity).
+        /// If `rhs > 0`, this is equal to rounding towards -infinity;
+        /// if `rhs < 0`, this is equal to rounding towards +infinity.
         ///
         /// # Panics
         ///
@@ -2823,8 +2825,8 @@ macro_rules! int_impl {
         /// Calculates the least nonnegative remainder of `self (mod rhs)`.
         ///
         /// This is done as if by the Euclidean division algorithm -- given
-        /// `r = self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
-        /// `0 <= r < abs(rhs)`.
+        /// `r = self.rem_euclid(rhs)`, the result satisfies
+        /// `self = rhs * self.div_euclid(rhs) + r` and `0 <= r < abs(rhs)`.
         ///
         /// # Panics
         ///
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 6661f6ee78b..a8a47b69632 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -237,7 +237,7 @@
 //! pointer. For code which *does* cast a usize to a pointer, the scope of the change depends
 //! on exactly what you're doing.
 //!
-//! In general you just need to make sure that if you want to convert a usize address to a
+//! In general, you just need to make sure that if you want to convert a usize address to a
 //! pointer and then use that pointer to read/write memory, you need to keep around a pointer
 //! that has sufficient provenance to perform that read/write itself. In this way all of your
 //! casts from an address to a pointer are essentially just applying offsets/indexing.
@@ -309,7 +309,7 @@
 //!   i.e. the usual "ZSTs are fake, do what you want" rules apply *but* this only applies
 //!   for actual forgery (integers cast to pointers). If you borrow some struct's field
 //!   that *happens* to be zero-sized, the resulting pointer will have provenance tied to
-//!   that allocation and it will still get invalidated if the allocation gets deallocated.
+//!   that allocation, and it will still get invalidated if the allocation gets deallocated.
 //!   In the future we may introduce an API to make such a forged allocation explicit.
 //!
 //! * [`wrapping_offset`][] a pointer outside its provenance. This includes pointers
@@ -698,7 +698,7 @@ pub const fn dangling_mut<T>() -> *mut T {
 ///
 /// If there is no 'exposed' provenance that justifies the way this pointer will be used,
 /// the program has undefined behavior. In particular, the aliasing rules still apply: pointers
-/// and references that have been invalidated due to aliasing accesses cannot be used any more,
+/// and references that have been invalidated due to aliasing accesses cannot be used anymore,
 /// even if they have been exposed!
 ///
 /// Note that there is no algorithm that decides which provenance will be used. You can think of this
@@ -1097,7 +1097,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
         // If we end up here, it's because we're using a simple type -- like
         // a small power-of-two-sized thing -- or a special type with particularly
         // large alignment, particularly SIMD types.
-        // Thus we're fine just reading-and-writing it, as either it's small
+        // Thus, we're fine just reading-and-writing it, as either it's small
         // and that works well anyway or it's special and the type's author
         // presumably wanted things to be done in the larger chunk.
 
@@ -1290,7 +1290,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
     // provides enough information to know that this is a typed operation.
 
     // However, as of March 2023 the compiler was not capable of taking advantage
-    // of that information.  Thus the implementation here switched to an intrinsic,
+    // of that information. Thus, the implementation here switched to an intrinsic,
     // which lowers to `_0 = *src` in MIR, to address a few issues:
     //
     // - Using `MaybeUninit::assume_init` after a `copy_nonoverlapping` was not
@@ -1570,7 +1570,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// As a result, using `&packed.unaligned as *const FieldType` causes immediate
 /// *undefined behavior* in your program.
 ///
-/// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut)
+/// Instead, you must use the [`ptr::addr_of_mut!`](addr_of_mut)
 /// macro to create the pointer. You may use that returned pointer together with
 /// this function.
 ///
diff --git a/library/std/src/os/hermit/io/mod.rs b/library/std/src/os/hermit/io/mod.rs
index 524dfae0d63..df93f63a003 100644
--- a/library/std/src/os/hermit/io/mod.rs
+++ b/library/std/src/os/hermit/io/mod.rs
@@ -1,13 +1,4 @@
-#![stable(feature = "os_fd", since = "1.66.0")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
-mod net;
-#[path = "../../fd/owned.rs"]
-mod owned;
-#[path = "../../fd/raw.rs"]
-mod raw;
-
-// Export the types and traits for the public API.
-#[stable(feature = "os_fd", since = "1.66.0")]
-pub use owned::*;
-#[stable(feature = "os_fd", since = "1.66.0")]
-pub use raw::*;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use crate::os::fd::*;
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index ca3584e82f9..d2a7b316b81 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -160,7 +160,7 @@ pub(crate) mod watchos;
 #[cfg(target_os = "xous")]
 pub mod xous;
 
-#[cfg(any(unix, target_os = "wasi", doc))]
+#[cfg(any(unix, target_os = "hermit", target_os = "wasi", doc))]
 pub mod fd;
 
 #[cfg(any(target_os = "linux", target_os = "android", doc))]
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index abf407ea91e..449d8c128ec 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -520,10 +520,12 @@ impl Build {
             return;
         }
 
-        // check_submodule
-        let checked_out_hash =
-            output(helpers::git(Some(&absolute_path)).args(["rev-parse", "HEAD"]));
-        // update_submodules
+        let submodule_git = || helpers::git(Some(&absolute_path));
+
+        // Determine commit checked out in submodule.
+        let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]));
+        let checked_out_hash = checked_out_hash.trim_end();
+        // Determine commit that the submodule *should* have.
         let recorded =
             output(helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path));
         let actual_hash = recorded
@@ -531,8 +533,7 @@ impl Build {
             .nth(2)
             .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
 
-        // update_submodule
-        if actual_hash == checked_out_hash.trim_end() {
+        if actual_hash == checked_out_hash {
             // already checked out
             return;
         }
@@ -581,26 +582,22 @@ impl Build {
         // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
         // diff-index reports the modifications through the exit status
         let has_local_modifications = !self.run_cmd(
-            BootstrapCommand::from(helpers::git(Some(&absolute_path)).args([
-                "diff-index",
-                "--quiet",
-                "HEAD",
-            ]))
-            .allow_failure()
-            .output_mode(match self.is_verbose() {
-                true => OutputMode::PrintAll,
-                false => OutputMode::PrintOutput,
-            }),
+            BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"]))
+                .allow_failure()
+                .output_mode(match self.is_verbose() {
+                    true => OutputMode::PrintAll,
+                    false => OutputMode::PrintOutput,
+                }),
         );
         if has_local_modifications {
-            self.run(helpers::git(Some(&absolute_path)).args(["stash", "push"]));
+            self.run(submodule_git().args(["stash", "push"]));
         }
 
-        self.run(helpers::git(Some(&absolute_path)).args(["reset", "-q", "--hard"]));
-        self.run(helpers::git(Some(&absolute_path)).args(["clean", "-qdfx"]));
+        self.run(submodule_git().args(["reset", "-q", "--hard"]));
+        self.run(submodule_git().args(["clean", "-qdfx"]));
 
         if has_local_modifications {
-            self.run(helpers::git(Some(&absolute_path)).args(["stash", "pop"]));
+            self.run(submodule_git().args(["stash", "pop"]));
         }
     }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 13d1346b3d9..4b6dc45b436 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -501,6 +501,16 @@ pub fn git(source_dir: Option<&Path>) -> Command {
 
     if let Some(source_dir) = source_dir {
         git.current_dir(source_dir);
+        // If we are running inside git (e.g. via a hook), `GIT_DIR` is set and takes precedence
+        // over the current dir. Un-set it to make the current dir matter.
+        git.env_remove("GIT_DIR");
+        // Also un-set some other variables, to be on the safe side (based on cargo's
+        // `fetch_with_cli`). In particular un-setting `GIT_INDEX_FILE` is required to fix some odd
+        // misbehavior.
+        git.env_remove("GIT_WORK_TREE")
+            .env_remove("GIT_INDEX_FILE")
+            .env_remove("GIT_OBJECT_DIRECTORY")
+            .env_remove("GIT_ALTERNATE_OBJECT_DIRECTORIES");
     }
 
     git
diff --git a/src/doc/book b/src/doc/book
-Subproject 5228bfac8267ad24659a81b92ec5417976b5edb
+Subproject 45c1a6d69edfd1fc91fb7504cb73958dbd09441
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject bbaabbe088e21a81a0d9ae6757705020d5d7b41
+Subproject cb58c430b4e8054c2cb81d2d4434092c482a93d
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 6019b76f5b28938565b251bbba0bf5cc5c43d86
+Subproject 0b805c65804019b0ac8f2fe3117afad82a6069b
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 4840dca06cadf48b305d3ce0aeafde7f80933f8
+Subproject b1d97bd6113aba732b2091ce093c76f2d05bb8a
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 6a7374bd87cbac0f8be4fd4877d8186d9c31398
+Subproject aec82168dd3121289a194b381f56076fc789a4d
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 74e39ffd933..313eac36337 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -57,7 +57,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 Ok(Some(ty::Instance {
-                    def: ty::InstanceDef::Item(instance.def_id()),
+                    def: ty::InstanceKind::Item(instance.def_id()),
                     args: instance.args,
                 }))
             }
diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs
index dab18dca2ff..f39bcfd60df 100644
--- a/src/tools/run-make-support/src/command.rs
+++ b/src/tools/run-make-support/src/command.rs
@@ -6,7 +6,7 @@ use std::path::Path;
 use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
 
 use crate::drop_bomb::DropBomb;
-use crate::{assert_contains, assert_not_contains, handle_failed_output};
+use crate::{assert_contains, assert_equals, assert_not_contains, handle_failed_output};
 
 /// This is a custom command wrapper that simplifies working with commands and makes it easier to
 /// ensure that we check the exit status of executed processes.
@@ -21,6 +21,7 @@ use crate::{assert_contains, assert_not_contains, handle_failed_output};
 ///
 /// [`run`]: Self::run
 /// [`run_fail`]: Self::run_fail
+/// [`run_unchecked`]: Self::run_unchecked
 #[derive(Debug)]
 pub struct Command {
     cmd: StdCommand,
@@ -116,6 +117,15 @@ impl Command {
         output
     }
 
+    /// Run the command but do not check its exit status.
+    /// Only use if you explicitly don't care about the exit status.
+    /// Prefer to use [`Self::run`] and [`Self::run_fail`]
+    /// whenever possible.
+    #[track_caller]
+    pub fn run_unchecked(&mut self) -> CompletedProcess {
+        self.command_output()
+    }
+
     #[track_caller]
     fn command_output(&mut self) -> CompletedProcess {
         self.drop_bomb.defuse();
@@ -163,41 +173,45 @@ impl CompletedProcess {
         self.output.status
     }
 
-    /// Checks that trimmed `stdout` matches trimmed `content`.
+    /// Checks that trimmed `stdout` matches trimmed `expected`.
     #[track_caller]
-    pub fn assert_stdout_equals<S: AsRef<str>>(&self, content: S) -> &Self {
-        assert_eq!(self.stdout_utf8().trim(), content.as_ref().trim());
+    pub fn assert_stdout_equals<S: AsRef<str>>(&self, expected: S) -> &Self {
+        assert_equals(self.stdout_utf8().trim(), expected.as_ref().trim());
         self
     }
 
+    /// Checks that `stdout` does not contain `unexpected`.
     #[track_caller]
-    pub fn assert_stdout_contains<S: AsRef<str>>(self, needle: S) -> Self {
-        assert_contains(&self.stdout_utf8(), needle.as_ref());
+    pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, unexpected: S) -> &Self {
+        assert_not_contains(&self.stdout_utf8(), unexpected.as_ref());
         self
     }
 
+    /// Checks that `stdout` contains `expected`.
     #[track_caller]
-    pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
-        assert_not_contains(&self.stdout_utf8(), needle.as_ref());
+    pub fn assert_stdout_contains<S: AsRef<str>>(&self, expected: S) -> &Self {
+        assert_contains(&self.stdout_utf8(), expected.as_ref());
         self
     }
 
-    /// Checks that trimmed `stderr` matches trimmed `content`.
+    /// Checks that trimmed `stderr` matches trimmed `expected`.
     #[track_caller]
-    pub fn assert_stderr_equals<S: AsRef<str>>(&self, content: S) -> &Self {
-        assert_eq!(self.stderr_utf8().trim(), content.as_ref().trim());
+    pub fn assert_stderr_equals<S: AsRef<str>>(&self, expected: S) -> &Self {
+        assert_equals(self.stderr_utf8().trim(), expected.as_ref().trim());
         self
     }
 
+    /// Checks that `stderr` contains `expected`.
     #[track_caller]
-    pub fn assert_stderr_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
-        assert_contains(&self.stderr_utf8(), needle.as_ref());
+    pub fn assert_stderr_contains<S: AsRef<str>>(&self, expected: S) -> &Self {
+        assert_contains(&self.stderr_utf8(), expected.as_ref());
         self
     }
 
+    /// Checks that `stderr` does not contain `unexpected`.
     #[track_caller]
-    pub fn assert_stderr_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
-        assert_not_contains(&self.stdout_utf8(), needle.as_ref());
+    pub fn assert_stderr_not_contains<S: AsRef<str>>(&self, unexpected: S) -> &Self {
+        assert_not_contains(&self.stdout_utf8(), unexpected.as_ref());
         self
     }
 
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index ba4524c150c..a358ae83de1 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -214,6 +214,38 @@ pub fn cwd() -> PathBuf {
     env::current_dir().unwrap()
 }
 
+// FIXME(Oneirical): This will no longer be required after compiletest receives the ability
+// to manipulate read-only files. See https://github.com/rust-lang/rust/issues/126334
+/// Ensure that the path P is read-only while the test runs, and restore original permissions
+/// at the end so compiletest can clean up.
+/// This will panic on Windows if the path is a directory (as it would otherwise do nothing)
+#[track_caller]
+pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>(
+    path: P,
+    closure: F,
+) {
+    let path = path.as_ref();
+    if is_windows() && path.is_dir() {
+        eprintln!("This helper function cannot be used on Windows to make directories readonly.");
+        eprintln!(
+            "See the official documentation:
+            https://doc.rust-lang.org/std/fs/struct.Permissions.html#method.set_readonly"
+        );
+        panic!("`test_while_readonly` on directory detected while on Windows.");
+    }
+    let metadata = fs_wrapper::metadata(&path);
+    let original_perms = metadata.permissions();
+
+    let mut new_perms = original_perms.clone();
+    new_perms.set_readonly(true);
+    fs_wrapper::set_permissions(&path, new_perms);
+
+    let success = std::panic::catch_unwind(closure);
+
+    fs_wrapper::set_permissions(&path, original_perms);
+    success.unwrap();
+}
+
 /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
 /// available on the platform!
 #[track_caller]
@@ -332,6 +364,18 @@ pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
     }
 }
 
+/// Check that `actual` is equal to `expected`. Panic otherwise.
+#[track_caller]
+pub fn assert_equals(actual: &str, expected: &str) {
+    if actual != expected {
+        eprintln!("=== ACTUAL TEXT ===");
+        eprintln!("{}", actual);
+        eprintln!("=== EXPECTED ===");
+        eprintln!("{}", expected);
+        panic!("expected text was not found in actual text");
+    }
+}
+
 /// Check that `haystack` contains `needle`. Panic otherwise.
 #[track_caller]
 pub fn assert_contains(haystack: &str, needle: &str) {
@@ -468,6 +512,15 @@ macro_rules! impl_common_helpers {
                 self.cmd.run_fail()
             }
 
+            /// Run the command but do not check its exit status.
+            /// Only use if you explicitly don't care about the exit status.
+            /// Prefer to use [`Self::run`] and [`Self::run_fail`]
+            /// whenever possible.
+            #[track_caller]
+            pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
+                self.cmd.run_unchecked()
+            }
+
             /// Set the path where the command will be run.
             pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
                 self.cmd.current_dir(path);
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index fdd0be79a4d..895798d7c1f 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -61,7 +61,6 @@ run-make/foreign-double-unwind/Makefile
 run-make/foreign-exceptions/Makefile
 run-make/foreign-rust-exceptions/Makefile
 run-make/glibc-staticlib-args/Makefile
-run-make/inaccessible-temp-dir/Makefile
 run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
@@ -74,7 +73,6 @@ run-make/invalid-library/Makefile
 run-make/invalid-so/Makefile
 run-make/invalid-staticlib/Makefile
 run-make/issue-107094/Makefile
-run-make/issue-10971-temps-dir/Makefile
 run-make/issue-109934-lto-debuginfo/Makefile
 run-make/issue-14698/Makefile
 run-make/issue-15460/Makefile
@@ -83,7 +81,6 @@ run-make/issue-20626/Makefile
 run-make/issue-22131/Makefile
 run-make/issue-25581/Makefile
 run-make/issue-26006/Makefile
-run-make/issue-26092/Makefile
 run-make/issue-28595/Makefile
 run-make/issue-33329/Makefile
 run-make/issue-35164/Makefile
@@ -109,10 +106,8 @@ run-make/libtest-json/Makefile
 run-make/libtest-junit/Makefile
 run-make/libtest-padding/Makefile
 run-make/libtest-thread-limit/Makefile
-run-make/link-arg/Makefile
 run-make/link-args-order/Makefile
 run-make/link-cfg/Makefile
-run-make/link-dedup/Makefile
 run-make/link-framework/Makefile
 run-make/link-path-order/Makefile
 run-make/linkage-attr-on-static/Makefile
@@ -153,7 +148,6 @@ run-make/optimization-remarks-dir/Makefile
 run-make/output-filename-conflicts-with-directory/Makefile
 run-make/output-filename-overwrites-input/Makefile
 run-make/output-type-permutations/Makefile
-run-make/output-with-hyphens/Makefile
 run-make/override-aliased-flags/Makefile
 run-make/overwrite-input/Makefile
 run-make/panic-abort-eh_frame/Makefile
diff --git a/tests/codegen/error-provide.rs b/tests/codegen/error-provide.rs
new file mode 100644
index 00000000000..68dd383e5cc
--- /dev/null
+++ b/tests/codegen/error-provide.rs
@@ -0,0 +1,50 @@
+// Codegen test for #126242
+
+//@ compile-flags: -O
+#![crate_type = "lib"]
+#![feature(error_generic_member_access)]
+use std::error::Request;
+use std::fmt;
+
+#[derive(Debug)]
+struct MyBacktrace1 {}
+
+#[derive(Debug)]
+struct MyBacktrace2 {}
+
+#[derive(Debug)]
+struct MyBacktrace3 {}
+
+#[derive(Debug)]
+struct MyError {
+    backtrace1: MyBacktrace1,
+    backtrace2: MyBacktrace2,
+    backtrace3: MyBacktrace3,
+    other: MyBacktrace3,
+}
+
+impl fmt::Display for MyError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "Example Error")
+    }
+}
+
+impl std::error::Error for MyError {
+    // CHECK-LABEL: @provide
+    #[no_mangle]
+    fn provide<'a>(&'a self, request: &mut Request<'a>) {
+        // LLVM should be able to optimize multiple .provide_* calls into a switch table
+        // and eliminate redundant ones, rather than compare one-by-one.
+
+        // CHECK-NEXT: start:
+        // CHECK-NEXT: %[[SCRUTINEE:[^ ]+]] = load i64, ptr
+        // CHECK-NEXT: switch i64 %[[SCRUTINEE]], label %{{.*}} [
+        // CHECK-COUNT-3: i64 {{.*}}, label %{{.*}}
+        // CHECK-NEXT: ]
+        request
+            .provide_ref::<MyBacktrace1>(&self.backtrace1)
+            .provide_ref::<MyBacktrace3>(&self.other)
+            .provide_ref::<MyBacktrace2>(&self.backtrace2)
+            .provide_ref::<MyBacktrace3>(&self.backtrace3);
+    }
+}
diff --git a/tests/crashes/126062.rs b/tests/crashes/126062.rs
deleted file mode 100644
index 9f1bec1d46e..00000000000
--- a/tests/crashes/126062.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: rust-lang/rust#126062
-struct Fail<T>(Fail);
-impl<T> Fail<i32> {
-    const C: () = panic!();
-}
-
-fn f<T>() {
-    if false {
-        let _val = &Fail::<T>::C;
-    }
-}
diff --git a/tests/crashes/126376.rs b/tests/crashes/126376.rs
deleted file mode 100644
index 028dde6d438..00000000000
--- a/tests/crashes/126376.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: rust-lang/rust#126376
-mod a {
-    pub mod b {
-        pub mod c {
-            pub trait D {}
-        }
-    }
-}
-
-use a::*;
-use e as b;
-use b::c::D as e;
-
-fn e() {}
diff --git a/tests/crashes/126385.rs b/tests/crashes/126385.rs
deleted file mode 100644
index 9e74e88c1ff..00000000000
--- a/tests/crashes/126385.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: rust-lang/rust#126385
-pub struct MyStruct<'field> {
-    field: &'_ [u32],
-}
-
-impl MyStruct<'_> {
-    pub fn _<'a>(field: &'a[u32]) -> Self<new> {
-    Self{field}
-    }
-}
diff --git a/tests/crashes/126389.rs b/tests/crashes/126389.rs
deleted file mode 100644
index 7aa6ecad9a3..00000000000
--- a/tests/crashes/126389.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: rust-lang/rust#126389
-
-mod a {
-    pub mod b {
-        pub mod c {}
-    }
-}
-
-use a::*;
-
-use b::c;
-
-use c as b;
-
-fn c() {}
diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
index b3227b79559..d937514c2ca 100644
--- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
+++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
@@ -12,7 +12,6 @@ fn main() {
 
     let output =
         rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();
-
     let version = fs_wrapper::read_to_string(source_root().join("src/version"));
     let expected_string = format!("stable since {}", version.trim());
     output.assert_stderr_contains(expected_string);
diff --git a/tests/run-make/issue-26092/blank.rs b/tests/run-make/clear-error-blank-output/blank.rs
index f328e4d9d04..f328e4d9d04 100644
--- a/tests/run-make/issue-26092/blank.rs
+++ b/tests/run-make/clear-error-blank-output/blank.rs
diff --git a/tests/run-make/clear-error-blank-output/rmake.rs b/tests/run-make/clear-error-blank-output/rmake.rs
new file mode 100644
index 00000000000..e0f042cf805
--- /dev/null
+++ b/tests/run-make/clear-error-blank-output/rmake.rs
@@ -0,0 +1,13 @@
+// When an empty output file is passed to rustc, the ensuing error message
+// should be clear. However, calling file_stem on an empty path returns None,
+// which, when unwrapped, causes a panic, stopping execution of rustc
+// and printing an obscure message instead of reaching the helpful
+// error message. This test checks that the panic does not occur.
+// See https://github.com/rust-lang/rust/pull/26199
+
+use run_make_support::rustc;
+
+fn main() {
+    let output = rustc().output("").stdin(b"fn main() {}").run_fail();
+    output.assert_stderr_not_contains("panic");
+}
diff --git a/tests/run-make/const_fn_mir/rmake.rs b/tests/run-make/const_fn_mir/rmake.rs
index a4cc4299b1b..1ba93421855 100644
--- a/tests/run-make/const_fn_mir/rmake.rs
+++ b/tests/run-make/const_fn_mir/rmake.rs
@@ -1,5 +1,7 @@
 // The `needs-unwind -Cpanic=abort` gives a different MIR output.
 
+//@ needs-unwind
+
 use run_make_support::{cwd, diff, rustc};
 
 fn main() {
diff --git a/tests/run-make/inaccessible-temp-dir/Makefile b/tests/run-make/inaccessible-temp-dir/Makefile
deleted file mode 100644
index abdba4eb861..00000000000
--- a/tests/run-make/inaccessible-temp-dir/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# only-linux
-# ignore-arm - linker error on `armhf-gnu`
-
-include ../tools.mk
-
-# Issue #66530: We would ICE if someone compiled with `-o /dev/null`,
-# because we would try to generate auxiliary files in `/dev/` (which
-# at least the OS X file system rejects).
-#
-# An attempt to `-Ztemps-dir` into a directory we cannot write into should
-# indeed be an error; but not an ICE.
-#
-# However, some folks run tests as root, which can write `/dev/` and end
-# up clobbering `/dev/null`. Instead we'll use an inaccessible path, which
-# also used to ICE, but even root can't magically write there.
-#
-# Note that `-Ztemps-dir` uses `create_dir_all` so it is not sufficient to
-# use a directory with non-existing parent like `/does-not-exist/output`.
-
-all:
-	# Create an inaccessible directory
-	mkdir $(TMPDIR)/inaccessible
-	chmod 000 $(TMPDIR)/inaccessible
-
-	# Run rustc with `-Ztemps-dir` set to a directory 
-	# *inside* the inaccessible one, so that it can't create it
-	$(RUSTC) program.rs -Ztemps-dir=$(TMPDIR)/inaccessible/tmp 2>&1 \
-		| $(CGREP) 'failed to find or create the directory specified by `--temps-dir`'
-
-	# Make the inaccessible directory accessible,
-	# so that compiletest can delete the temp dir
-	chmod +rw $(TMPDIR)/inaccessible
diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs
new file mode 100644
index 00000000000..be24e47b6de
--- /dev/null
+++ b/tests/run-make/inaccessible-temp-dir/rmake.rs
@@ -0,0 +1,38 @@
+// Issue #66530: We would ICE if someone compiled with `-o /dev/null`,
+// because we would try to generate auxiliary files in `/dev/` (which
+// at least the OS X file system rejects).
+//
+// An attempt to `-Ztemps-dir` into a directory we cannot write into should
+// indeed be an error; but not an ICE.
+//
+// However, some folks run tests as root, which can write `/dev/` and end
+// up clobbering `/dev/null`. Instead we'll use an inaccessible path, which
+// also used to ICE, but even root can't magically write there.
+//
+// Note that `-Ztemps-dir` uses `create_dir_all` so it is not sufficient to
+// use a directory with non-existing parent like `/does-not-exist/output`.
+// See https://github.com/rust-lang/rust/issues/66530
+
+//@ ignore-arm
+// Reason: linker error on `armhf-gnu`
+//@ ignore-windows
+// Reason: `set_readonly` has no effect on directories
+// and does not prevent modification.
+
+use run_make_support::{fs_wrapper, rustc, test_while_readonly};
+
+fn main() {
+    // Create an inaccessible directory.
+    fs_wrapper::create_dir("inaccessible");
+    test_while_readonly("inaccessible", || {
+        // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one,
+        // so that it can't create `tmp`.
+        rustc()
+            .input("program.rs")
+            .arg("-Ztemps-dir=inaccessible/tmp")
+            .run_fail()
+            .assert_stderr_contains(
+                "failed to find or create the directory specified by `--temps-dir`",
+            );
+    });
+}
diff --git a/tests/run-make/issue-10971-temps-dir/Makefile b/tests/run-make/issue-10971-temps-dir/Makefile
deleted file mode 100644
index 6e1649a58d2..00000000000
--- a/tests/run-make/issue-10971-temps-dir/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include ../tools.mk
-
-# Regression test for issue #10971
-# Running two invocations in parallel would overwrite each other's temp files.
-
-all:
-	touch $(TMPDIR)/lib.rs
-
-	$(RUSTC) --crate-type=lib -Z temps-dir=$(TMPDIR)/temp1 $(TMPDIR)/lib.rs & \
-	$(RUSTC) --crate-type=staticlib -Z temps-dir=$(TMPDIR)/temp2 $(TMPDIR)/lib.rs
diff --git a/tests/run-make/issue-26092/Makefile b/tests/run-make/issue-26092/Makefile
deleted file mode 100644
index 96822e7690b..00000000000
--- a/tests/run-make/issue-26092/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-include ../tools.mk
-
-# This test ensures that rustc does not panic with `-o ""` option.
-
-all:
-	$(RUSTC) -o "" blank.rs 2>&1 | $(CGREP) -i 'panic' && exit 1 || exit 0
diff --git a/tests/run-make/issue-47551/Makefile b/tests/run-make/issue-47551/Makefile
index 5a6ac725701..3fe0a6e74e0 100644
--- a/tests/run-make/issue-47551/Makefile
+++ b/tests/run-make/issue-47551/Makefile
@@ -4,6 +4,7 @@
 include ../tools.mk
 
 all:
-	$(RUSTC) eh_frame-terminator.rs
+	# --target $(TARGET) ensures the right gcc flags are used for cross compilation
+	$(RUSTC) --target $(TARGET) eh_frame-terminator.rs
 	$(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788'
 	objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator'
diff --git a/tests/run-make/link-arg/Makefile b/tests/run-make/link-arg/Makefile
deleted file mode 100644
index 103527c3e14..00000000000
--- a/tests/run-make/link-arg/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-include ../tools.mk
-RUSTC_FLAGS = -C link-arg="-lfoo" -C link-arg="-lbar" --print link-args
-
-all:
-	$(RUSTC) $(RUSTC_FLAGS) empty.rs | $(CGREP) lfoo lbar
diff --git a/tests/run-make/link-arg/rmake.rs b/tests/run-make/link-arg/rmake.rs
new file mode 100644
index 00000000000..a6d68800792
--- /dev/null
+++ b/tests/run-make/link-arg/rmake.rs
@@ -0,0 +1,20 @@
+// In 2016, the rustc flag "-C link-arg" was introduced - it can be repeatedly used
+// to add single arguments to the linker. This test passes 2 arguments to the linker using it,
+// then checks that the compiler's output contains the arguments passed to it.
+// This ensures that the compiler successfully parses this flag.
+// See https://github.com/rust-lang/rust/pull/36574
+
+use run_make_support::rustc;
+
+fn main() {
+    // We are only checking for the output of --print=link-args,
+    // rustc failing or succeeding does not matter.
+    let out = rustc()
+        .input("empty.rs")
+        .link_arg("-lfoo")
+        .link_arg("-lbar")
+        .print("link-args")
+        .run_unchecked();
+    out.assert_stdout_contains("lfoo");
+    out.assert_stdout_contains("lbar");
+}
diff --git a/tests/run-make/link-dedup/Makefile b/tests/run-make/link-dedup/Makefile
deleted file mode 100644
index eff18ab48ab..00000000000
--- a/tests/run-make/link-dedup/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# ignore-msvc
-
-include ../tools.mk
-
-all:
-	$(RUSTC) depa.rs
-	$(RUSTC) depb.rs
-	$(RUSTC) depc.rs
-	$(RUSTC) empty.rs --cfg bar 2>&1 | $(CGREP) '"-ltesta" "-ltestb" "-ltesta"'
-	$(RUSTC) empty.rs 2>&1 | $(CGREP) '"-ltesta"'
-	$(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltestb"'
-	$(RUSTC) empty.rs 2>&1 | $(CGREP) -v '"-ltesta" "-ltesta" "-ltesta"'
diff --git a/tests/run-make/link-dedup/rmake.rs b/tests/run-make/link-dedup/rmake.rs
new file mode 100644
index 00000000000..9bff3a4b44c
--- /dev/null
+++ b/tests/run-make/link-dedup/rmake.rs
@@ -0,0 +1,24 @@
+// When native libraries are passed to the linker, there used to be an annoyance
+// where multiple instances of the same library in a row would cause duplication in
+// outputs. This has been fixed, and this test checks that it stays fixed.
+// With the --cfg flag, -ltestb gets added to the output, breaking up the chain of -ltesta.
+// Without the --cfg flag, there should be a single -ltesta, no more, no less.
+// See https://github.com/rust-lang/rust/pull/84794
+
+//@ ignore-msvc
+
+use run_make_support::rustc;
+
+fn main() {
+    rustc().input("depa.rs").run();
+    rustc().input("depb.rs").run();
+    rustc().input("depc.rs").run();
+    let output = rustc().input("empty.rs").cfg("bar").run_fail();
+    output.assert_stderr_contains(r#""-ltesta" "-ltestb" "-ltesta""#);
+    let output = rustc().input("empty.rs").run_fail();
+    output.assert_stderr_contains(r#""-ltesta""#);
+    let output = rustc().input("empty.rs").run_fail();
+    output.assert_stderr_not_contains(r#""-ltestb""#);
+    let output = rustc().input("empty.rs").run_fail();
+    output.assert_stderr_not_contains(r#""-ltesta" "-ltesta" "-ltesta""#);
+}
diff --git a/tests/run-make/output-with-hyphens/Makefile b/tests/run-make/output-with-hyphens/Makefile
deleted file mode 100644
index 846c9a66a89..00000000000
--- a/tests/run-make/output-with-hyphens/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) foo-bar.rs --crate-type bin
-	[ -f $(TMPDIR)/$(call BIN,foo-bar) ]
-	$(RUSTC) foo-bar.rs --crate-type lib
-	[ -f $(TMPDIR)/libfoo_bar.rlib ]
diff --git a/tests/run-make/output-with-hyphens/rmake.rs b/tests/run-make/output-with-hyphens/rmake.rs
new file mode 100644
index 00000000000..79deb772bc5
--- /dev/null
+++ b/tests/run-make/output-with-hyphens/rmake.rs
@@ -0,0 +1,17 @@
+// Rust files with hyphens in their filename should
+// not result in compiled libraries keeping that hyphen -
+// it should become an underscore. Only bin executables
+// should keep the hyphen. This test ensures that this rule
+// remains enforced.
+// See https://github.com/rust-lang/rust/pull/23786
+
+//@ ignore-cross-compile
+
+use run_make_support::{bin_name, path, rust_lib_name, rustc};
+
+fn main() {
+    rustc().input("foo-bar.rs").crate_type("bin").run();
+    assert!(path(bin_name("foo-bar")).exists());
+    rustc().input("foo-bar.rs").crate_type("lib").run();
+    assert!(path(rust_lib_name("foo_bar")).exists());
+}
diff --git a/tests/run-make/parallel-rustc-no-overwrite/rmake.rs b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs
new file mode 100644
index 00000000000..3f032cf3762
--- /dev/null
+++ b/tests/run-make/parallel-rustc-no-overwrite/rmake.rs
@@ -0,0 +1,25 @@
+// When two instances of rustc are invoked in parallel, they
+// can conflict on their temporary files and overwrite each others',
+// leading to unsuccessful compilation. The -Z temps-dir flag adds
+// separate designated directories for each rustc invocation, preventing
+// conflicts. This test uses this flag and checks for successful compilation.
+// See https://github.com/rust-lang/rust/pull/83846
+
+use run_make_support::{fs_wrapper, rustc};
+use std::sync::{Arc, Barrier};
+use std::thread;
+
+fn main() {
+    fs_wrapper::create_file("lib.rs");
+    let barrier = Arc::new(Barrier::new(2));
+    let handle = {
+        let barrier = Arc::clone(&barrier);
+        thread::spawn(move || {
+            barrier.wait();
+            rustc().crate_type("lib").arg("-Ztemps-dir=temp1").input("lib.rs").run();
+        })
+    };
+    barrier.wait();
+    rustc().crate_type("staticlib").arg("-Ztemps-dir=temp2").input("lib.rs").run();
+    handle.join().expect("lib thread panicked");
+}
diff --git a/tests/ui/associated-consts/double-elided.rs b/tests/ui/associated-consts/double-elided.rs
index fd0317781bb..6831b599374 100644
--- a/tests/ui/associated-consts/double-elided.rs
+++ b/tests/ui/associated-consts/double-elided.rs
@@ -1,12 +1,10 @@
+//@ check-pass
+
 struct S;
 
 impl S {
     const C: &&str = &"";
-    //~^ WARN `&` without an explicit lifetime name cannot be used here
-    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    //~| WARN `&` without an explicit lifetime name cannot be used here
-    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    //~| ERROR in type `&&str`, reference has a longer lifetime than the data it references
+    // Now resolves to `&'static &'static str`.
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/double-elided.stderr b/tests/ui/associated-consts/double-elided.stderr
deleted file mode 100644
index 67834788ccd..00000000000
--- a/tests/ui/associated-consts/double-elided.stderr
+++ /dev/null
@@ -1,47 +0,0 @@
-warning: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/double-elided.rs:4:14
-   |
-LL |     const C: &&str = &"";
-   |              ^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
-   = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
-help: use the `'static` lifetime
-   |
-LL |     const C: &'static &str = &"";
-   |               +++++++
-
-warning: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/double-elided.rs:4:15
-   |
-LL |     const C: &&str = &"";
-   |               ^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
-help: use the `'static` lifetime
-   |
-LL |     const C: &&'static str = &"";
-   |                +++++++
-
-error[E0491]: in type `&&str`, reference has a longer lifetime than the data it references
-  --> $DIR/double-elided.rs:4:5
-   |
-LL |     const C: &&str = &"";
-   |     ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the pointer is valid for the anonymous lifetime as defined here
-  --> $DIR/double-elided.rs:4:14
-   |
-LL |     const C: &&str = &"";
-   |              ^
-note: but the referenced data is only valid for the anonymous lifetime as defined here
-  --> $DIR/double-elided.rs:4:14
-   |
-LL |     const C: &&str = &"";
-   |              ^
-
-error: aborting due to 1 previous error; 2 warnings emitted
-
-For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
index 1e0b77b0d3b..40896c32e11 100644
--- a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.rs
@@ -5,8 +5,6 @@ trait Trait {
 impl Trait for () {
     const ASSOC: &dyn Fn(_) = 1i32;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
-    //~| WARN `&` without an explicit lifetime name cannot be used here
-    //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 }
 
 fn main() {}
diff --git a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
index e946491a084..6b8ba9af7a0 100644
--- a/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
+++ b/tests/ui/associated-consts/infer-placeholder-in-non-suggestable-pos.stderr
@@ -1,23 +1,9 @@
-warning: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:18
-   |
-LL |     const ASSOC: &dyn Fn(_) = 1i32;
-   |                  ^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
-   = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
-help: use the `'static` lifetime
-   |
-LL |     const ASSOC: &'static dyn Fn(_) = 1i32;
-   |                   +++++++
-
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
   --> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26
    |
 LL |     const ASSOC: &dyn Fn(_) = 1i32;
    |                          ^ not allowed in type signatures
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
new file mode 100644
index 00000000000..e2fc2961a44
--- /dev/null
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
@@ -0,0 +1,10 @@
+struct Fail<T>;
+//~^ ERROR: type parameter `T` is never used
+
+impl Fail<i32> {
+    const C: () = ();
+}
+
+fn main() {
+    Fail::<()>::C
+}
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
new file mode 100644
index 00000000000..f0a6ccf243a
--- /dev/null
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
@@ -0,0 +1,12 @@
+error[E0392]: type parameter `T` is never used
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:1:13
+   |
+LL | struct Fail<T>;
+   |             ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
new file mode 100644
index 00000000000..cb53d902ba1
--- /dev/null
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
@@ -0,0 +1,17 @@
+trait Proj {
+    type Assoc;
+}
+impl<T> Proj for T {
+    type Assoc = T;
+}
+
+struct Fail<T: Proj<Assoc = U>, U>(T);
+
+impl Fail<i32, i32> {
+    const C: () = ();
+}
+
+fn main() {
+    Fail::<i32, u32>::C
+    //~^ ERROR: type mismatch
+}
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
new file mode 100644
index 00000000000..0d63b7f5b29
--- /dev/null
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<i32 as Proj>::Assoc == u32`
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5
+   |
+LL |     Fail::<i32, u32>::C
+   |     ^^^^^^^^^^^^^^^^ type mismatch resolving `<i32 as Proj>::Assoc == u32`
+   |
+note: expected this to be `u32`
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:5:18
+   |
+LL |     type Assoc = T;
+   |                  ^
+note: required by a bound in `Fail`
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:8:21
+   |
+LL | struct Fail<T: Proj<Assoc = U>, U>(T);
+   |                     ^^^^^^^^^ required by this bound in `Fail`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs
new file mode 100644
index 00000000000..637c47f2939
--- /dev/null
+++ b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.rs
@@ -0,0 +1,14 @@
+// This test was triggering a `span_bug` crash, which was then fixed by
+// downgrading it to a `span_delayed_bug`.
+
+pub struct MyStruct<'field> {
+    field: &'field [u32],
+}
+
+impl MyStruct<'_> {
+    pub fn f(field: &[u32]) -> Self<u32> { //~ ERROR type arguments are not allowed on self type
+        Self { field }                     //~ ERROR lifetime may not live long enough
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr
new file mode 100644
index 00000000000..0ae301b2090
--- /dev/null
+++ b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr
@@ -0,0 +1,34 @@
+error[E0109]: type arguments are not allowed on self type
+  --> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:9:37
+   |
+LL |     pub fn f(field: &[u32]) -> Self<u32> {
+   |                                ---- ^^^ type argument not allowed
+   |                                |
+   |                                not allowed on self type
+   |
+note: `Self` is of type `MyStruct<'_>`
+  --> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:4:12
+   |
+LL | pub struct MyStruct<'field> {
+   |            ^^^^^^^^ `Self` corresponds to this type
+...
+LL | impl MyStruct<'_> {
+   | ----------------- `Self` is on type `MyStruct` in this `impl`
+help: the `Self` type doesn't accept type parameters, use the concrete type's name `MyStruct` instead if you want to specify its type parameters
+   |
+LL |     pub fn f(field: &[u32]) -> MyStruct<u32> {
+   |                                ~~~~~~~~
+
+error: lifetime may not live long enough
+  --> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:10:9
+   |
+LL |     pub fn f(field: &[u32]) -> Self<u32> {
+   |                     -          --------- return type is MyStruct<'2>
+   |                     |
+   |                     let's call the lifetime of this reference `'1`
+LL |         Self { field }
+   |         ^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/tests/ui/closures/wrong-closure-arg-suggestion-125325.rs b/tests/ui/closures/wrong-closure-arg-suggestion-125325.rs
new file mode 100644
index 00000000000..ce575697cf6
--- /dev/null
+++ b/tests/ui/closures/wrong-closure-arg-suggestion-125325.rs
@@ -0,0 +1,29 @@
+// Regression test for #125325
+
+// Tests that we suggest changing an `impl Fn` param
+// to `impl FnMut` when the provided closure arg
+// is trying to mutate the closure env.
+// Ensures that it works that way for both
+// functions and methods
+
+struct S;
+
+impl S {
+    fn assoc_func(&self, _f: impl Fn()) -> usize {
+        0
+    }
+}
+
+fn func(_f: impl Fn()) -> usize {
+    0
+}
+
+fn test_func(s: &S) -> usize {
+    let mut x = ();
+    s.assoc_func(|| x = ());
+    //~^ cannot assign to `x`, as it is a captured variable in a `Fn` closure
+    func(|| x = ())
+    //~^ cannot assign to `x`, as it is a captured variable in a `Fn` closure
+}
+
+fn main() {}
diff --git a/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr
new file mode 100644
index 00000000000..e0cce8c4b31
--- /dev/null
+++ b/tests/ui/closures/wrong-closure-arg-suggestion-125325.stderr
@@ -0,0 +1,28 @@
+error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
+  --> $DIR/wrong-closure-arg-suggestion-125325.rs:23:21
+   |
+LL |     fn assoc_func(&self, _f: impl Fn()) -> usize {
+   |                              --------- change this to accept `FnMut` instead of `Fn`
+...
+LL |     s.assoc_func(|| x = ());
+   |       --------------^^^^^^-
+   |       |          |  |
+   |       |          |  cannot assign
+   |       |          in this closure
+   |       expects `Fn` instead of `FnMut`
+
+error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
+  --> $DIR/wrong-closure-arg-suggestion-125325.rs:25:13
+   |
+LL | fn func(_f: impl Fn()) -> usize {
+   |             --------- change this to accept `FnMut` instead of `Fn`
+...
+LL |     func(|| x = ())
+   |     ---- -- ^^^^^^ cannot assign
+   |     |    |
+   |     |    in this closure
+   |     expects `Fn` instead of `FnMut`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0594`.
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
deleted file mode 100644
index b976f70acf7..00000000000
--- a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0277]: the trait bound `(): std::error::Error` is not satisfied
-  --> $DIR/coerce-issue-49593-box-never-windows.rs:18:53
-   |
-LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
-   |
-   = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
-
-error[E0277]: the trait bound `(): std::error::Error` is not satisfied
-  --> $DIR/coerce-issue-49593-box-never-windows.rs:23:49
-   |
-LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
-   |
-   = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never-windows.rs b/tests/ui/coercion/coerce-issue-49593-box-never-windows.rs
deleted file mode 100644
index b317841ab6e..00000000000
--- a/tests/ui/coercion/coerce-issue-49593-box-never-windows.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-//@ revisions: nofallback fallback
-//@ only-windows - the number of `Error` impls is platform-dependent
-//@[fallback] check-pass
-//@[nofallback] check-fail
-
-#![feature(never_type)]
-#![cfg_attr(fallback, feature(never_type_fallback))]
-#![allow(unreachable_code)]
-
-use std::error::Error;
-use std::mem;
-
-fn raw_ptr_box<T>(t: T) -> *mut T {
-    panic!()
-}
-
-fn foo(x: !) -> Box<dyn Error> {
-    /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
-    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
-}
-
-fn foo_raw_ptr(x: !) -> *mut dyn Error {
-    /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
-    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
-}
-
-fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
-    /* an unsize coercion won't compile here, and it is indeed not used
-       because there is nothing requiring the _ to be Sized */
-    d as *mut _
-}
-
-trait Xyz {}
-struct S;
-struct T;
-impl Xyz for S {}
-impl Xyz for T {}
-
-fn foo_no_never() {
-    let mut x /* : Option<S> */ = None;
-    let mut first_iter = false;
-    loop {
-        if !first_iter {
-            let y: Box<dyn Xyz>
-                = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
-        }
-
-        x = Some(S);
-        first_iter = true;
-    }
-
-    let mut y : Option<S> = None;
-    // assert types are equal
-    mem::swap(&mut x, &mut y);
-}
-
-fn main() {
-}
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr
new file mode 100644
index 00000000000..ef5633f7134
--- /dev/null
+++ b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `(): std::error::Error` is not satisfied
+  --> $DIR/coerce-issue-49593-box-never.rs:18:5
+   |
+LL |     Box::<_ /* ! */>::new(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
+   |
+   = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
index 0d98fa93e5a..7222af43b01 100644
--- a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
+++ b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
@@ -1,16 +1,16 @@
 error[E0277]: the trait bound `(): std::error::Error` is not satisfied
-  --> $DIR/coerce-issue-49593-box-never.rs:18:53
+  --> $DIR/coerce-issue-49593-box-never.rs:18:5
    |
-LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
+LL |     Box::<_ /* ! */>::new(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
    = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
 
 error[E0277]: the trait bound `(): std::error::Error` is not satisfied
-  --> $DIR/coerce-issue-49593-box-never.rs:23:49
+  --> $DIR/coerce-issue-49593-box-never.rs:24:5
    |
-LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
+LL |     raw_ptr_box::<_ /* ! */>(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
    = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
 
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.rs b/tests/ui/coercion/coerce-issue-49593-box-never.rs
index 19a2c036fbc..53071be47dc 100644
--- a/tests/ui/coercion/coerce-issue-49593-box-never.rs
+++ b/tests/ui/coercion/coerce-issue-49593-box-never.rs
@@ -1,7 +1,5 @@
 //@ revisions: nofallback fallback
-//@ ignore-windows - the number of `Error` impls is platform-dependent
-//@[fallback] check-pass
-//@[nofallback] check-fail
+//@check-fail
 
 #![feature(never_type)]
 #![cfg_attr(fallback, feature(never_type_fallback))]
@@ -15,18 +13,21 @@ fn raw_ptr_box<T>(t: T) -> *mut T {
 }
 
 fn foo(x: !) -> Box<dyn Error> {
-    /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
-    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
+    // Subtyping during method resolution will generate new inference vars and
+    // subtype them. Thus fallback will not fall back to `!`, but `()` instead.
+    Box::<_ /* ! */>::new(x)
+    //~^ ERROR trait bound `(): std::error::Error` is not satisfied
 }
 
 fn foo_raw_ptr(x: !) -> *mut dyn Error {
-    /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
+    /* *mut $0 is coerced to *mut Error here */
+    raw_ptr_box::<_ /* ! */>(x)
     //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
 }
 
 fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
     /* an unsize coercion won't compile here, and it is indeed not used
-       because there is nothing requiring the _ to be Sized */
+    because there is nothing requiring the _ to be Sized */
     d as *mut _
 }
 
@@ -49,10 +50,9 @@ fn foo_no_never() {
         first_iter = true;
     }
 
-    let mut y : Option<S> = None;
+    let mut y: Option<S> = None;
     // assert types are equal
     mem::swap(&mut x, &mut y);
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 5ee42c19dd3..563406ad5ea 100644
--- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -15,7 +15,7 @@ note: required by a bound in `Mask::<T, N>::splat`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
 help: consider giving `y` an explicit type, where the type for type parameter `T` is specified
    |
-LL |     let y: Mask<_, N> = Mask::<_, _>::splat(false);
+LL |     let y: Mask<T, N> = Mask::<_, _>::splat(false);
    |          ++++++++++++
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/consts/assoc-const-elided-lifetime.stderr b/tests/ui/consts/assoc-const-elided-lifetime.stderr
index a1eeaff4ba8..3e847298c35 100644
--- a/tests/ui/consts/assoc-const-elided-lifetime.stderr
+++ b/tests/ui/consts/assoc-const-elided-lifetime.stderr
@@ -6,6 +6,11 @@ LL |     const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/assoc-const-elided-lifetime.rs:9:6
+   |
+LL | impl<'a> Foo<'a> {
+   |      ^^
 note: the lint level is defined here
   --> $DIR/assoc-const-elided-lifetime.rs:1:9
    |
@@ -24,6 +29,13 @@ LL |     const BAR: &() = &();
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/assoc-const-elided-lifetime.rs:9:6
+   |
+LL | impl<'a> Foo<'a> {
+   |      ^^
+LL |     const FOO: Foo<'_> = Foo { x: PhantomData::<&()> };
+   |                    ^^
 help: use the `'static` lifetime
    |
 LL |     const BAR: &'static () = &();
diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs
new file mode 100644
index 00000000000..95d59f9b894
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs
@@ -0,0 +1,22 @@
+#![deny(elided_lifetimes_in_associated_constant)]
+
+struct Foo<'a>(&'a ());
+
+impl Foo<'_> {
+    const STATIC: &str = "";
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out
+}
+
+trait Bar {
+    const STATIC: &str;
+}
+
+impl Bar for Foo<'_> {
+    const STATIC: &str = "";
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out
+    //~| ERROR const not compatible with trait
+}
+
+fn main() {}
diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
new file mode 100644
index 00000000000..d4fc1717538
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr
@@ -0,0 +1,59 @@
+error: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/elided-lifetime.rs:6:19
+   |
+LL |     const STATIC: &str = "";
+   |                   ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/elided-lifetime.rs:5:10
+   |
+LL | impl Foo<'_> {
+   |          ^^
+note: the lint level is defined here
+  --> $DIR/elided-lifetime.rs:1:9
+   |
+LL | #![deny(elided_lifetimes_in_associated_constant)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the `'static` lifetime
+   |
+LL |     const STATIC: &'static str = "";
+   |                    +++++++
+
+error: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/elided-lifetime.rs:16:19
+   |
+LL |     const STATIC: &str = "";
+   |                   ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/elided-lifetime.rs:15:18
+   |
+LL | impl Bar for Foo<'_> {
+   |                  ^^
+help: use the `'static` lifetime
+   |
+LL |     const STATIC: &'static str = "";
+   |                    +++++++
+
+error[E0308]: const not compatible with trait
+  --> $DIR/elided-lifetime.rs:16:5
+   |
+LL |     const STATIC: &str = "";
+   |     ^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected reference `&'static _`
+              found reference `&_`
+note: the anonymous lifetime as defined here...
+  --> $DIR/elided-lifetime.rs:15:18
+   |
+LL | impl Bar for Foo<'_> {
+   |                  ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.rs b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs
new file mode 100644
index 00000000000..721920bd810
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.rs
@@ -0,0 +1,19 @@
+#![deny(elided_lifetimes_in_associated_constant)]
+#![feature(generic_const_items)]
+//~^ WARN the feature `generic_const_items` is incomplete
+
+struct A;
+impl A {
+    const GAC_TYPE<T>: &str = "";
+    const GAC_LIFETIME<'a>: &str = "";
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out
+}
+
+trait Trait {
+    const GAC_TYPE<T>: &str = "";
+    const GAC_LIFETIME<'a>: &str = "";
+    //~^ ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr
new file mode 100644
index 00000000000..2ecab3442a9
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/generic-associated-const.stderr
@@ -0,0 +1,46 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/generic-associated-const.rs:15:29
+   |
+LL |     const GAC_LIFETIME<'a>: &str = "";
+   |                             ^ expected named lifetime parameter
+   |
+help: consider using the `'a` lifetime
+   |
+LL |     const GAC_LIFETIME<'a>: &'a str = "";
+   |                              ++
+
+warning: the feature `generic_const_items` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/generic-associated-const.rs:2:12
+   |
+LL | #![feature(generic_const_items)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #113521 <https://github.com/rust-lang/rust/issues/113521> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/generic-associated-const.rs:8:29
+   |
+LL |     const GAC_LIFETIME<'a>: &str = "";
+   |                             ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/generic-associated-const.rs:8:24
+   |
+LL |     const GAC_LIFETIME<'a>: &str = "";
+   |                        ^^
+note: the lint level is defined here
+  --> $DIR/generic-associated-const.rs:1:9
+   |
+LL | #![deny(elided_lifetimes_in_associated_constant)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the `'static` lifetime
+   |
+LL |     const GAC_LIFETIME<'a>: &'static str = "";
+   |                              +++++++
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/consts/static-default-lifetime/inner-item.rs b/tests/ui/consts/static-default-lifetime/inner-item.rs
new file mode 100644
index 00000000000..061b240a40d
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/inner-item.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+
+struct Foo<'a>(&'a ());
+
+impl<'a> Foo<'a> {
+    fn hello(self) {
+        const INNER: &str = "";
+    }
+}
+
+impl Foo<'_> {
+    fn implicit(self) {
+        const INNER: &str = "";
+    }
+
+    fn fn_lifetime(&self) {
+        const INNER: &str = "";
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
new file mode 100644
index 00000000000..025fda4df58
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
@@ -0,0 +1,20 @@
+#![deny(elided_lifetimes_in_associated_constant)]
+
+trait Bar<'a> {
+    const STATIC: &'a str;
+}
+
+struct A;
+impl Bar<'_> for A {
+    const STATIC: &str = "";
+    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~| WARN this was previously accepted by the compiler but is being phased out
+    //~| ERROR const not compatible with trait
+}
+
+struct B;
+impl Bar<'static> for B {
+    const STATIC: &str = "";
+}
+
+fn main() {}
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
new file mode 100644
index 00000000000..8e4c27875ab
--- /dev/null
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr
@@ -0,0 +1,45 @@
+error: `&` without an explicit lifetime name cannot be used here
+  --> $DIR/static-trait-impl.rs:9:19
+   |
+LL |     const STATIC: &str = "";
+   |                   ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
+note: cannot automatically infer `'static` because of other lifetimes in scope
+  --> $DIR/static-trait-impl.rs:8:10
+   |
+LL | impl Bar<'_> for A {
+   |          ^^
+note: the lint level is defined here
+  --> $DIR/static-trait-impl.rs:1:9
+   |
+LL | #![deny(elided_lifetimes_in_associated_constant)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use the `'static` lifetime
+   |
+LL |     const STATIC: &'static str = "";
+   |                    +++++++
+
+error[E0308]: const not compatible with trait
+  --> $DIR/static-trait-impl.rs:9:5
+   |
+LL |     const STATIC: &str = "";
+   |     ^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected reference `&_`
+              found reference `&_`
+note: the anonymous lifetime as defined here...
+  --> $DIR/static-trait-impl.rs:8:10
+   |
+LL | impl Bar<'_> for A {
+   |          ^^
+note: ...does not necessarily outlive the anonymous lifetime as defined here
+  --> $DIR/static-trait-impl.rs:8:10
+   |
+LL | impl Bar<'_> for A {
+   |          ^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/imports/shadow-glob-module-resolution-3.rs b/tests/ui/imports/shadow-glob-module-resolution-3.rs
new file mode 100644
index 00000000000..f5a43373261
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-3.rs
@@ -0,0 +1,19 @@
+// https://github.com/rust-lang/rust/issues/126389
+
+mod a {
+    pub mod b {
+        pub mod c {}
+    }
+}
+
+use a::*;
+
+use b::c;
+//~^ ERROR: unresolved import `b::c`
+//~| ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+use c as b;
+
+fn c() {}
+
+fn main() { }
diff --git a/tests/ui/imports/shadow-glob-module-resolution-3.stderr b/tests/ui/imports/shadow-glob-module-resolution-3.stderr
new file mode 100644
index 00000000000..ab853c71582
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-3.stderr
@@ -0,0 +1,23 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-3.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-3.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `b::c`
+  --> $DIR/shadow-glob-module-resolution-3.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/shadow-glob-module-resolution-4.rs b/tests/ui/imports/shadow-glob-module-resolution-4.rs
new file mode 100644
index 00000000000..581cdc185d3
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-4.rs
@@ -0,0 +1,20 @@
+// https://github.com/rust-lang/rust/issues/126376
+
+mod a {
+    pub mod b {
+        pub trait C {}
+    }
+}
+
+use a::*;
+
+use e as b;
+
+use b::C as e;
+//~^ ERROR: unresolved import `b::C`
+//~| ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+
+fn e() {}
+
+fn main() { }
diff --git a/tests/ui/imports/shadow-glob-module-resolution-4.stderr b/tests/ui/imports/shadow-glob-module-resolution-4.stderr
new file mode 100644
index 00000000000..063beb612b1
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-4.stderr
@@ -0,0 +1,23 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-4.rs:13:5
+   |
+LL | use b::C as e;
+   |     ^^^^^^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-4.rs:13:5
+   |
+LL | use b::C as e;
+   |     ^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `b::C`
+  --> $DIR/shadow-glob-module-resolution-4.rs:13:5
+   |
+LL | use b::C as e;
+   |     ^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.stderr b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
index 535c0044aec..5c5b4c149c1 100644
--- a/tests/ui/inference/need_type_info/type-alias-indirect.stderr
+++ b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/type-alias-indirect.rs:14:5
    |
 LL |     IndirectAlias::new();
-   |     ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr
index 2c39a3f5646..fd9bcf2fe3f 100644
--- a/tests/ui/inference/need_type_info/type-alias.stderr
+++ b/tests/ui/inference/need_type_info/type-alias.stderr
@@ -2,19 +2,19 @@ error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:12:5
    |
 LL |     DirectAlias::new()
-   |     ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+   |     ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias`
 
 error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:18:5
    |
 LL |     IndirectAlias::new();
-   |     ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
 
 error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:32:5
    |
 LL |     DirectButWithDefaultAlias::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/crashes/122736.rs b/tests/ui/privacy/no-ice-on-inference-failure.rs
index 83b60444c2f..e63b7bff9bc 100644
--- a/tests/crashes/122736.rs
+++ b/tests/ui/privacy/no-ice-on-inference-failure.rs
@@ -1,9 +1,9 @@
-//@ known-bug: #122736
 fn main_ref() {
     let array = [(); {
         let mut x = &0;
         let mut n = 0;
         while n < 5 {
+            //~^ ERROR constant evaluation is taking a long time
             x = &0;
         }
         0
diff --git a/tests/ui/privacy/no-ice-on-inference-failure.stderr b/tests/ui/privacy/no-ice-on-inference-failure.stderr
new file mode 100644
index 00000000000..67476e6e218
--- /dev/null
+++ b/tests/ui/privacy/no-ice-on-inference-failure.stderr
@@ -0,0 +1,27 @@
+error: constant evaluation is taking a long time
+  --> $DIR/no-ice-on-inference-failure.rs:5:9
+   |
+LL | /         while n < 5 {
+LL | |
+LL | |             x = &0;
+LL | |         }
+   | |_________^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/no-ice-on-inference-failure.rs:2:22
+   |
+LL |       let array = [(); {
+   |  ______________________^
+LL | |         let mut x = &0;
+LL | |         let mut n = 0;
+LL | |         while n < 5 {
+...  |
+LL | |         0
+LL | |     }];
+   | |_____^
+   = note: `#[deny(long_running_const_eval)]` on by default
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/statics/const_generics.rs b/tests/ui/statics/const_generics.rs
new file mode 100644
index 00000000000..70d9b933a76
--- /dev/null
+++ b/tests/ui/statics/const_generics.rs
@@ -0,0 +1,26 @@
+//! Check that we lose the information that `BAR` points to `FOO`
+//! when going through a const generic.
+//! This is not an intentional guarantee, it just describes the status quo.
+
+//@ run-pass
+// With optimizations, LLVM will deduplicate the constant `X` whose
+// value is `&42` to just be a reference to the static. This is correct,
+// but obscures the issue we're trying to show.
+//@ revisions: opt noopt
+//@[noopt] compile-flags: -Copt-level=0
+//@[opt] compile-flags: -O
+
+#![feature(const_refs_to_static)]
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+static FOO: usize = 42;
+const BAR: &usize = &FOO;
+fn foo<const X: &'static usize>() {
+    // Without optimizations, `X` ends up pointing to a copy of `FOO` instead of `FOO` itself.
+    assert_eq!(cfg!(opt), std::ptr::eq(X, &FOO));
+}
+
+fn main() {
+    foo::<BAR>();
+}
diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr
index 24e2e0a0f7a..71ac55bf044 100644
--- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr
+++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.default.stderr
@@ -1,57 +1,25 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14
-   |
-LL |     const A: &str = "";
-   |              ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL ~ trait ZstAssert<'a>: Sized {
-LL ~     const A: &'a str = "";
-   |
-
-error[E0106]: missing lifetime specifier
+error[E0726]: implicit elided lifetime not allowed here
   --> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
    |
 LL |     const B: S = S { s: &() };
-   |              ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL ~ trait ZstAssert<'a>: Sized {
-LL |     const A: &str = "";
-LL ~     const B: S<'a> = S { s: &() };
+   |              ^ expected lifetime parameter
    |
-
-error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15
-   |
-LL |     const C: &'_ str = "";
-   |               ^^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL ~ trait ZstAssert<'a>: Sized {
-LL |     const A: &str = "";
-LL |     const B: S = S { s: &() };
-LL ~     const C: &'a str = "";
+help: indicate the anonymous lifetime
    |
+LL |     const B: S<'_> = S { s: &() };
+   |               ++++
 
-error[E0106]: missing lifetime specifiers
+error[E0726]: implicit elided lifetime not allowed here
   --> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
    |
 LL |     const D: T = T { a: &(), b: &() };
-   |              ^ expected 2 lifetime parameters
-   |
-help: consider introducing a named lifetime parameter
+   |              ^ expected lifetime parameters
    |
-LL ~ trait ZstAssert<'a>: Sized {
-LL |     const A: &str = "";
-LL |     const B: S = S { s: &() };
-LL |     const C: &'_ str = "";
-LL ~     const D: T<'a, 'a> = T { a: &(), b: &() };
+help: indicate the anonymous lifetimes
    |
+LL |     const D: T<'_, '_> = T { a: &(), b: &() };
+   |               ++++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0726`.
diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr
index a97ffe7da79..71ac55bf044 100644
--- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr
+++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.generic_const_items.stderr
@@ -1,47 +1,25 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-in-assoc-const-type.rs:6:14
-   |
-LL |     const A: &str = "";
-   |              ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL |     const A<'a>: &'a str = "";
-   |            ++++   ++
-
-error[E0106]: missing lifetime specifier
+error[E0726]: implicit elided lifetime not allowed here
   --> $DIR/missing-lifetime-in-assoc-const-type.rs:7:14
    |
 LL |     const B: S = S { s: &() };
-   |              ^ expected named lifetime parameter
-   |
-help: consider introducing a named lifetime parameter
-   |
-LL |     const B<'a>: S<'a> = S { s: &() };
-   |            ++++   ++++
-
-error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-in-assoc-const-type.rs:8:15
-   |
-LL |     const C: &'_ str = "";
-   |               ^^ expected named lifetime parameter
+   |              ^ expected lifetime parameter
    |
-help: consider introducing a named lifetime parameter
+help: indicate the anonymous lifetime
    |
-LL |     const C<'a>: &'a str = "";
-   |            ++++   ~~
+LL |     const B: S<'_> = S { s: &() };
+   |               ++++
 
-error[E0106]: missing lifetime specifiers
+error[E0726]: implicit elided lifetime not allowed here
   --> $DIR/missing-lifetime-in-assoc-const-type.rs:9:14
    |
 LL |     const D: T = T { a: &(), b: &() };
-   |              ^ expected 2 lifetime parameters
+   |              ^ expected lifetime parameters
    |
-help: consider introducing a named lifetime parameter
+help: indicate the anonymous lifetimes
    |
-LL |     const D<'a>: T<'a, 'a> = T { a: &(), b: &() };
-   |            ++++   ++++++++
+LL |     const D: T<'_, '_> = T { a: &(), b: &() };
+   |               ++++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0726`.
diff --git a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs
index f36a6567e42..a60f0b94587 100644
--- a/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs
+++ b/tests/ui/suggestions/missing-lifetime-in-assoc-const-type.rs
@@ -3,10 +3,10 @@
 #![cfg_attr(generic_const_items, feature(generic_const_items), allow(incomplete_features))]
 
 trait ZstAssert: Sized {
-    const A: &str = ""; //~ ERROR missing lifetime specifier
-    const B: S = S { s: &() }; //~ ERROR missing lifetime specifier
-    const C: &'_ str = ""; //~ ERROR missing lifetime specifier
-    const D: T = T { a: &(), b: &() }; //~ ERROR missing lifetime specifier
+    const A: &str = "";
+    const B: S = S { s: &() }; //~ ERROR implicit elided lifetime not allowed here
+    const C: &'_ str = "";
+    const D: T = T { a: &(), b: &() }; //~ ERROR implicit elided lifetime not allowed here
 }
 
 struct S<'a> {
diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
index 66e1e77c905..924bfd82eb8 100644
--- a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
+++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
@@ -17,6 +17,7 @@ fn main() {
     let fp = BufWriter::new(fp);
     //~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
     //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
+    //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
 
     writeln!(fp, "hello world").unwrap(); //~ ERROR the method
 }
diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
index 09a9b1d3b34..b2f9150142f 100644
--- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
+++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
@@ -14,6 +14,16 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satis
   --> $DIR/mut-borrow-needed-by-trait.rs:17:14
    |
 LL |     let fp = BufWriter::new(fp);
+   |              ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
+   |
+   = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
+note: required by a bound in `BufWriter`
+  --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
+
+error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
+  --> $DIR/mut-borrow-needed-by-trait.rs:17:14
+   |
+LL |     let fp = BufWriter::new(fp);
    |              ^^^^^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
    |
    = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
@@ -21,13 +31,13 @@ note: required by a bound in `BufWriter`
   --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
 
 error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:22:14
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |     ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
    |
 note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
-  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:22:14
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |              ^^
@@ -35,7 +45,7 @@ LL |     writeln!(fp, "hello world").unwrap();
            `&dyn std::io::Write: std::io::Write`
            which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0599.
 For more information about an error, try `rustc --explain E0277`.