about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-25 12:46:16 +0000
committerbors <bors@rust-lang.org>2024-05-25 12:46:16 +0000
commit331bb3f10d755f4c7fdf29b21d7a957a76f76c1a (patch)
tree49508f89e82532e4551483117d3f6ad1162eb1e7
parent008f6b3a3f454c23deae23c2660f9ff7f2854dd4 (diff)
parent1d0ad049936322ddbafe9d9379ba3d860995ad19 (diff)
downloadrust-331bb3f10d755f4c7fdf29b21d7a957a76f76c1a.tar.gz
rust-331bb3f10d755f4c7fdf29b21d7a957a76f76c1a.zip
Auto merge of #3630 - rust-lang:rustup-2024-05-25, r=saethlin
Automatic Rustup
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/check.rs)0
-rw-r--r--compiler/rustc_const_eval/src/check_consts/mod.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/mod.rs)0
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/ops.rs)0
-rw-r--r--compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs)0
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs)0
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs (renamed from compiler/rustc_const_eval/src/transform/check_consts/resolver.rs)0
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs7
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs122
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl4
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs40
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs5
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs3
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs105
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs17
-rw-r--r--compiler/rustc_lint/src/for_loops_over_fallibles.rs4
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs42
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs28
-rw-r--r--compiler/rustc_mir_transform/Cargo.toml1
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs4
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs2
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs (renamed from compiler/rustc_const_eval/src/transform/validate.rs)9
-rw-r--r--library/core/benches/str/debug.rs4
-rw-r--r--library/core/src/cmp.rs1
-rw-r--r--library/core/src/fmt/mod.rs59
-rw-r--r--library/core/src/intrinsics/simd.rs8
-rw-r--r--library/core/src/ptr/metadata.rs27
-rw-r--r--library/std/src/sys/mod.rs2
-rw-r--r--library/std/src/sys/thread_local/fast_local/lazy.rs1
-rw-r--r--library/std/src/sys/thread_local/mod.rs87
-rw-r--r--library/std/src/sys/thread_local/os_local.rs162
-rw-r--r--library/test/src/bench.rs2
-rw-r--r--src/bootstrap/README.md2
-rw-r--r--src/bootstrap/src/core/builder/tests.rs29
-rw-r--r--src/bootstrap/src/core/sanity.rs10
-rw-r--r--src/tools/build_helper/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/panic/mir-validation.stderr2
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/crashes/118403.rs8
-rw-r--r--tests/crashes/121574-2.rs8
-rw-r--r--tests/crashes/121574.rs6
-rw-r--r--tests/crashes/124833.rs10
-rw-r--r--tests/crashes/124891.rs22
-rw-r--r--tests/run-make/rustdoc-with-output-option/Makefile8
-rw-r--r--tests/run-make/rustdoc-with-output-option/rmake.rs16
-rw-r--r--tests/rustdoc-json/keyword_private.rs20
-rw-r--r--tests/ui/binop/nested-assignment-may-be-deref.rs14
-rw-r--r--tests/ui/binop/nested-assignment-may-be-deref.stderr29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs13
-rw-r--r--tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr11
-rw-r--r--tests/ui/generic-const-items/assoc-const-missing-type.rs21
-rw-r--r--tests/ui/generic-const-items/assoc-const-missing-type.stderr48
-rw-r--r--tests/ui/impl-trait/lazy_subtyping_of_opaques.rs59
-rw-r--r--tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr21
-rw-r--r--tests/ui/malformed/do-not-ice-on-note_and_explain.rs17
-rw-r--r--tests/ui/malformed/do-not-ice-on-note_and_explain.stderr85
-rw-r--r--tests/ui/self/self-ctor-nongeneric.rs4
-rw-r--r--tests/ui/self/self-ctor-nongeneric.stderr27
-rw-r--r--tests/ui/self/self-ctor.rs14
-rw-r--r--tests/ui/self/self-ctor.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr26
-rw-r--r--triagebot.toml5
72 files changed, 810 insertions, 585 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3a4f028e695..92e6a22b4b9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4252,6 +4252,7 @@ dependencies = [
  "rustc_fluent_macro",
  "rustc_hir",
  "rustc_index",
+ "rustc_infer",
  "rustc_macros",
  "rustc_middle",
  "rustc_mir_build",
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index b4556f8fcb8..5d7eb052561 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -29,8 +29,8 @@ use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, Debugger
 use rustc_middle::middle::exported_symbols;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_middle::middle::lang_items;
-use rustc_middle::mir::BinOp;
 use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
+use rustc_middle::mir::BinOp;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 5fbf5b41109..5fbf5b41109 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs
index 308b90cd470..308b90cd470 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/check_consts/mod.rs
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 8406e0f4876..8406e0f4876 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
index f0763f1e490..f0763f1e490 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 5949444e599..5949444e599 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 011341472b4..011341472b4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 7a1c2a7b6fa..650669ac690 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -139,10 +139,9 @@ where
             ErrorHandled::TooGeneric(span)
         }
         err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span),
-        err_inval!(Layout(LayoutError::ReferencesError(guar))) => ErrorHandled::Reported(
-            ReportedErrorInfo::tainted_by_errors(guar),
-            span,
-        ),
+        err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
+            ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span)
+        }
         // Report remaining errors.
         _ => {
             let (our_span, frames) = get_span_and_frames();
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index b14780c0d98..3a7c87c1cad 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -14,10 +14,10 @@
 #![feature(yeet_expr)]
 #![feature(if_let_guard)]
 
+pub mod check_consts;
 pub mod const_eval;
 mod errors;
 pub mod interpret;
-pub mod transform;
 pub mod util;
 
 use std::sync::atomic::AtomicBool;
diff --git a/compiler/rustc_const_eval/src/transform/mod.rs b/compiler/rustc_const_eval/src/transform/mod.rs
deleted file mode 100644
index e3582c7d317..00000000000
--- a/compiler/rustc_const_eval/src/transform/mod.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-pub mod check_consts;
-pub mod validate;
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 50fe20346cf..8506b8d75f9 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -164,9 +164,8 @@ pub fn check_intrinsic_type(
 ) {
     let generics = tcx.generics_of(intrinsic_id);
     let param = |n| {
-        if let Some(&ty::GenericParamDef {
-            name, kind: ty::GenericParamDefKind::Type { .. }, ..
-        }) = generics.opt_param_at(n as usize, tcx)
+        if let &ty::GenericParamDef { name, kind: ty::GenericParamDefKind::Type { .. }, .. } =
+            generics.param_at(n as usize, tcx)
         {
             Ty::new_param(tcx, n, name)
         } else {
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index db36aba7edf..606f1653767 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -461,83 +461,55 @@ pub(super) fn explicit_predicates_of<'tcx>(
             }
         }
     } else {
-        if matches!(def_kind, DefKind::AnonConst) && tcx.features().generic_const_exprs {
-            let hir_id = tcx.local_def_id_to_hir_id(def_id);
-            let parent_def_id = tcx.hir().get_parent_item(hir_id);
-
-            if let Some(defaulted_param_def_id) =
-                tcx.hir().opt_const_param_default_param_def_id(hir_id)
-            {
-                // In `generics_of` we set the generics' parent to be our parent's parent which means that
-                // we lose out on the predicates of our actual parent if we dont return those predicates here.
-                // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
-                //
-                // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
-                //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
-                //        ^^^                                             explicit_predicates_of on
-                //        parent item we dont have set as the
-                //        parent of generics returned by `generics_of`
-                //
-                // In the above code we want the anon const to have predicates in its param env for `T: Trait`
-                // and we would be calling `explicit_predicates_of(Foo)` here
-                let parent_preds = tcx.explicit_predicates_of(parent_def_id);
-
-                // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
-                // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
-                // to #106994 is implemented.
-                let filtered_predicates = parent_preds
-                    .predicates
-                    .into_iter()
-                    .filter(|(pred, _)| {
-                        if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
-                            match ct.kind() {
-                                ty::ConstKind::Param(param_const) => {
-                                    let defaulted_param_idx = tcx
-                                        .generics_of(parent_def_id)
-                                        .param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
-                                    param_const.index < defaulted_param_idx
-                                }
-                                _ => bug!(
-                                    "`ConstArgHasType` in `predicates_of`\
-                                 that isn't a `Param` const"
-                                ),
+        if matches!(def_kind, DefKind::AnonConst)
+            && tcx.features().generic_const_exprs
+            && let Some(defaulted_param_def_id) =
+                tcx.hir().opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
+        {
+            // In `generics_of` we set the generics' parent to be our parent's parent which means that
+            // we lose out on the predicates of our actual parent if we dont return those predicates here.
+            // (See comment in `generics_of` for more information on why the parent shenanigans is necessary)
+            //
+            // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait;
+            //        ^^^                     ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling
+            //        ^^^                                             explicit_predicates_of on
+            //        parent item we dont have set as the
+            //        parent of generics returned by `generics_of`
+            //
+            // In the above code we want the anon const to have predicates in its param env for `T: Trait`
+            // and we would be calling `explicit_predicates_of(Foo)` here
+            let parent_def_id = tcx.local_parent(def_id);
+            let parent_preds = tcx.explicit_predicates_of(parent_def_id);
+
+            // If we dont filter out `ConstArgHasType` predicates then every single defaulted const parameter
+            // will ICE because of #106994. FIXME(generic_const_exprs): remove this when a more general solution
+            // to #106994 is implemented.
+            let filtered_predicates = parent_preds
+                .predicates
+                .into_iter()
+                .filter(|(pred, _)| {
+                    if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
+                        match ct.kind() {
+                            ty::ConstKind::Param(param_const) => {
+                                let defaulted_param_idx = tcx
+                                    .generics_of(parent_def_id)
+                                    .param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
+                                param_const.index < defaulted_param_idx
                             }
-                        } else {
-                            true
+                            _ => bug!(
+                                "`ConstArgHasType` in `predicates_of`\
+                                 that isn't a `Param` const"
+                            ),
                         }
-                    })
-                    .cloned();
-                return GenericPredicates {
-                    parent: parent_preds.parent,
-                    predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
-                };
-            }
-
-            let parent_def_kind = tcx.def_kind(parent_def_id);
-            if matches!(parent_def_kind, DefKind::OpaqueTy) {
-                // In `instantiate_identity` we inherit the predicates of our parent.
-                // However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means
-                // that we lose out on the predicates of our actual parent if we dont return those predicates here.
-                //
-                //
-                // fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() }
-                //                                                        ^^^^^^^^^^^^^^^^^^^ the def id we are calling
-                //                                                                            explicit_predicates_of on
-                //
-                // In the above code we want the anon const to have predicates in its param env for `T: Trait`.
-                // However, the anon const cannot inherit predicates from its parent since it's opaque.
-                //
-                // To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
-
-                // In the above example this is `foo::{opaque#0}` or `impl Iterator`
-                let parent_hir_id = tcx.local_def_id_to_hir_id(parent_def_id.def_id);
-
-                // In the above example this is the function `foo`
-                let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
-
-                // In the above code example we would be calling `explicit_predicates_of(foo)` here
-                return tcx.explicit_predicates_of(item_def_id);
-            }
+                    } else {
+                        true
+                    }
+                })
+                .cloned();
+            return GenericPredicates {
+                parent: parent_preds.parent,
+                predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
+            };
         }
         gather_explicit_predicates_of(tcx, def_id)
     }
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index 72b95a9603d..6f499947d5c 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -137,6 +137,10 @@ hir_typeck_rpit_change_return_type = you could change the return type to be a bo
 hir_typeck_rustcall_incorrect_args =
     functions with the "rust-call" ABI must take a single non-self tuple argument
 
+hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from outer item
+    .label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+    .suggestion = replace `Self` with the actual type
+
 hir_typeck_struct_expr_non_exhaustive =
     cannot create non-exhaustive {$what} using struct expression
 
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index f250b909596..3f12f252654 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -651,3 +651,31 @@ pub enum SuggestBoxingForReturnImplTrait {
         ends: Vec<Span>,
     },
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)]
+pub struct SelfCtorFromOuterItem {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub impl_span: Span,
+    #[subdiagnostic]
+    pub sugg: Option<ReplaceWithName>,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(hir_typeck_self_ctor_from_outer_item)]
+pub struct SelfCtorFromOuterItemLint {
+    #[label]
+    pub impl_span: Span,
+    #[subdiagnostic]
+    pub sugg: Option<ReplaceWithName>,
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")]
+pub struct ReplaceWithName {
+    #[primary_span]
+    pub span: Span,
+    pub name: String,
+}
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 77f90c0c131..074aca78933 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1,5 +1,5 @@
 use crate::callee::{self, DeferredCallResolution};
-use crate::errors::CtorIsPrivate;
+use crate::errors::{self, CtorIsPrivate};
 use crate::method::{self, MethodCallee, SelfSource};
 use crate::rvalue_scopes;
 use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
@@ -21,6 +21,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
+use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
@@ -1156,6 +1157,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 span,
                 tcx.at(span).type_of(impl_def_id).instantiate_identity(),
             );
+
+            // Firstly, check that this SelfCtor even comes from the item we're currently
+            // typechecking. This can happen because we never validated the resolution of
+            // SelfCtors, and when we started doing so, we noticed regressions. After
+            // sufficiently long time, we can remove this check and turn it into a hard
+            // error in `validate_res_from_ribs` -- it's just difficult to tell whether the
+            // self type has any generic types during rustc_resolve, which is what we use
+            // to determine if this is a hard error or warning.
+            if std::iter::successors(Some(self.body_id.to_def_id()), |def_id| {
+                self.tcx.generics_of(def_id).parent
+            })
+            .all(|def_id| def_id != impl_def_id)
+            {
+                let sugg = ty.normalized.ty_adt_def().map(|def| errors::ReplaceWithName {
+                    span: path_span,
+                    name: self.tcx.item_name(def.did()).to_ident_string(),
+                });
+                if ty.raw.has_param() {
+                    let guar = self.tcx.dcx().emit_err(errors::SelfCtorFromOuterItem {
+                        span: path_span,
+                        impl_span: tcx.def_span(impl_def_id),
+                        sugg,
+                    });
+                    return (Ty::new_error(self.tcx, guar), res);
+                } else {
+                    self.tcx.emit_node_span_lint(
+                        SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
+                        hir_id,
+                        path_span,
+                        errors::SelfCtorFromOuterItemLint {
+                            impl_span: tcx.def_span(impl_def_id),
+                            sugg,
+                        },
+                    );
+                }
+            }
+
             match ty.normalized.ty_adt_def() {
                 Some(adt_def) if adt_def.has_ctor() => {
                     let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index b9a99fbec3c..86fe2756b59 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -235,11 +235,17 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
         if let Some(item) = tcx.opt_associated_item(def_id.into())
             && let ty::AssocKind::Const = item.kind
             && let ty::ImplContainer = item.container
-            && let Some(trait_item) = item.trait_item_def_id
+            && let Some(trait_item_def_id) = item.trait_item_def_id
         {
-            let args =
-                tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args;
-            Some(tcx.type_of(trait_item).instantiate(tcx, args))
+            let impl_def_id = item.container_id(tcx);
+            let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
+            let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
+                tcx,
+                impl_def_id,
+                impl_trait_ref.args,
+            );
+            tcx.check_args_compatible(trait_item_def_id, args)
+                .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args))
         } else {
             Some(fcx.next_ty_var(span))
         }
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 87b76b978b9..25b74dca12f 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -381,10 +381,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let maybe_missing_semi = self.check_for_missing_semi(expr, &mut err);
 
                 // We defer to the later error produced by `check_lhs_assignable`.
-                // We only downgrade this if it's the LHS, though.
+                // We only downgrade this if it's the LHS, though, and if this is a
+                // valid assignment statement.
                 if maybe_missing_semi
                     && let hir::Node::Expr(parent) = self.tcx.parent_hir_node(expr.hir_id)
                     && let hir::ExprKind::Assign(lhs, _, _) = parent.kind
+                    && let hir::Node::Stmt(stmt) = self.tcx.parent_hir_node(parent.hir_id)
+                    && let hir::StmtKind::Expr(_) | hir::StmtKind::Semi(_) = stmt.kind
                     && lhs.hir_id == expr.hir_id
                 {
                     err.downgrade_to_delayed_bug();
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 6c3f73cf465..af667a57ce1 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -116,8 +116,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr
 
         if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
             // Decode the list of work_products
-            let Ok(mut work_product_decoder) =
-                MemDecoder::new(&work_products_data[..], start_pos)
+            let Ok(mut work_product_decoder) = MemDecoder::new(&work_products_data[..], start_pos)
             else {
                 sess.dcx().emit_warn(errors::CorruptFile { path: &work_products_path });
                 return LoadResult::DataOutOfDate;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index f2fe43380b8..f4514c23508 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -54,17 +54,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     }
                     (ty::Param(expected), ty::Param(found)) => {
                         let generics = tcx.generics_of(body_owner_def_id);
-                        if let Some(param) = generics.opt_type_param(expected, tcx) {
-                            let e_span = tcx.def_span(param.def_id);
-                            if !sp.contains(e_span) {
-                                diag.span_label(e_span, "expected type parameter");
-                            }
+                        let e_span = tcx.def_span(generics.type_param(expected, tcx).def_id);
+                        if !sp.contains(e_span) {
+                            diag.span_label(e_span, "expected type parameter");
                         }
-                        if let Some(param) = generics.opt_type_param(found, tcx) {
-                            let f_span = tcx.def_span(param.def_id);
-                            if !sp.contains(f_span) {
-                                diag.span_label(f_span, "found type parameter");
-                            }
+                        let f_span = tcx.def_span(generics.type_param(found, tcx).def_id);
+                        if !sp.contains(f_span) {
+                            diag.span_label(f_span, "found type parameter");
                         }
                         diag.note(
                             "a type parameter was expected, but a different one was found; \
@@ -87,29 +83,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     | (ty::Alias(ty::Projection, proj), ty::Param(p))
                         if !tcx.is_impl_trait_in_trait(proj.def_id) =>
                     {
-                        let parent = tcx
-                            .generics_of(body_owner_def_id)
-                            .opt_type_param(p, tcx)
-                            .and_then(|param| {
-                                let p_def_id = param.def_id;
-                                let p_span = tcx.def_span(p_def_id);
-                                let expected = match (values.expected.kind(), values.found.kind()) {
-                                    (ty::Param(_), _) => "expected ",
-                                    (_, ty::Param(_)) => "found ",
-                                    _ => "",
-                                };
-                                if !sp.contains(p_span) {
-                                    diag.span_label(
-                                        p_span,
-                                        format!("{expected}this type parameter"),
-                                    );
-                                }
-                                p_def_id.as_local().and_then(|id| {
-                                    let local_id = tcx.local_def_id_to_hir_id(id);
-                                    let generics = tcx.parent_hir_node(local_id).generics()?;
-                                    Some((id, generics))
-                                })
-                            });
+                        let param = tcx.generics_of(body_owner_def_id).type_param(p, tcx);
+                        let p_def_id = param.def_id;
+                        let p_span = tcx.def_span(p_def_id);
+                        let expected = match (values.expected.kind(), values.found.kind()) {
+                            (ty::Param(_), _) => "expected ",
+                            (_, ty::Param(_)) => "found ",
+                            _ => "",
+                        };
+                        if !sp.contains(p_span) {
+                            diag.span_label(p_span, format!("{expected}this type parameter"));
+                        }
+                        let parent = p_def_id.as_local().and_then(|id| {
+                            let local_id = tcx.local_def_id_to_hir_id(id);
+                            let generics = tcx.parent_hir_node(local_id).generics()?;
+                            Some((id, generics))
+                        });
                         let mut note = true;
                         if let Some((local_id, generics)) = parent {
                             // Synthesize the associated type restriction `Add<Output = Expected>`.
@@ -183,16 +172,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     (ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
                     | (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
                         let generics = tcx.generics_of(body_owner_def_id);
-                        if let Some(param) = generics.opt_type_param(p, tcx) {
-                            let p_span = tcx.def_span(param.def_id);
-                            let expected = match (values.expected.kind(), values.found.kind()) {
-                                (ty::Param(_), _) => "expected ",
-                                (_, ty::Param(_)) => "found ",
-                                _ => "",
-                            };
-                            if !sp.contains(p_span) {
-                                diag.span_label(p_span, format!("{expected}this type parameter"));
-                            }
+                        let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
+                        let expected = match (values.expected.kind(), values.found.kind()) {
+                            (ty::Param(_), _) => "expected ",
+                            (_, ty::Param(_)) => "found ",
+                            _ => "",
+                        };
+                        if !sp.contains(p_span) {
+                            diag.span_label(p_span, format!("{expected}this type parameter"));
                         }
                         diag.help("type parameters must be constrained to match other types");
                         if tcx.sess.teach(diag.code.unwrap()) {
@@ -233,11 +220,9 @@ impl<T> Trait<T> for X {
                         ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..),
                     ) => {
                         let generics = tcx.generics_of(body_owner_def_id);
-                        if let Some(param) = generics.opt_type_param(p, tcx) {
-                            let p_span = tcx.def_span(param.def_id);
-                            if !sp.contains(p_span) {
-                                diag.span_label(p_span, "expected this type parameter");
-                            }
+                        let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
+                        if !sp.contains(p_span) {
+                            diag.span_label(p_span, "expected this type parameter");
                         }
                         diag.help(format!(
                             "every closure has a distinct type and so could not always match the \
@@ -246,16 +231,14 @@ impl<T> Trait<T> for X {
                     }
                     (ty::Param(p), _) | (_, ty::Param(p)) => {
                         let generics = tcx.generics_of(body_owner_def_id);
-                        if let Some(param) = generics.opt_type_param(p, tcx) {
-                            let p_span = tcx.def_span(param.def_id);
-                            let expected = match (values.expected.kind(), values.found.kind()) {
-                                (ty::Param(_), _) => "expected ",
-                                (_, ty::Param(_)) => "found ",
-                                _ => "",
-                            };
-                            if !sp.contains(p_span) {
-                                diag.span_label(p_span, format!("{expected}this type parameter"));
-                            }
+                        let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
+                        let expected = match (values.expected.kind(), values.found.kind()) {
+                            (ty::Param(_), _) => "expected ",
+                            (_, ty::Param(_)) => "found ",
+                            _ => "",
+                        };
+                        if !sp.contains(p_span) {
+                            diag.span_label(p_span, format!("{expected}this type parameter"));
                         }
                     }
                     (ty::Alias(ty::Projection | ty::Inherent, proj_ty), _)
@@ -545,10 +528,8 @@ impl<T> Trait<T> for X {
             return false;
         };
         let generics = tcx.generics_of(body_owner_def_id);
-        let Some(param) = generics.opt_type_param(param_ty, tcx) else {
-            return false;
-        };
-        let Some(def_id) = param.def_id.as_local() else {
+        let def_id = generics.type_param(param_ty, tcx).def_id;
+        let Some(def_id) = def_id.as_local() else {
             return false;
         };
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 8d4011421bd..6f603d9b612 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -957,27 +957,14 @@ impl<'tcx> InferCtxt<'tcx> {
             (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
                 return Err((a_vid, b_vid));
             }
-            // We don't silently want to constrain hidden types here, so we assert that either one side is
-            // an infer var, so it'll get constrained to whatever the other side is, or there are no opaque
-            // types involved.
-            // We don't expect this to actually get hit, but if it does, we now at least know how to write
-            // a test for it.
-            (_, ty::Infer(ty::TyVar(_))) => {}
-            (ty::Infer(ty::TyVar(_)), _) => {}
-            _ if r_a != r_b && (r_a, r_b).has_opaque_types() => {
-                span_bug!(
-                    cause.span(),
-                    "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}"
-                )
-            }
             _ => {}
         }
 
         self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
             if a_is_expected {
-                Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
+                Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
             } else {
-                Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
+                Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
             }
         })
     }
diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
index b05f5e7638b..aa00fb4573d 100644
--- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs
+++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs
@@ -62,7 +62,9 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
         };
 
         let (article, ty, var) = match adt.did() {
-            did if cx.tcx.is_diagnostic_item(sym::Option, did) && ref_mutability.is_some() => ("a", "Option", "Some"),
+            did if cx.tcx.is_diagnostic_item(sym::Option, did) && ref_mutability.is_some() => {
+                ("a", "Option", "Some")
+            }
             did if cx.tcx.is_diagnostic_item(sym::Option, did) => ("an", "Option", "Some"),
             did if cx.tcx.is_diagnostic_item(sym::Result, did) => ("a", "Result", "Ok"),
             _ => return,
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 82f16b31a66..617fe99ef6a 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -90,6 +90,7 @@ declare_lint_pass! {
         RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
         RUST_2021_PRELUDE_COLLISIONS,
         RUST_2024_INCOMPATIBLE_PAT,
+        SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
         SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
         SINGLE_USE_LIFETIMES,
         SOFT_UNSTABLE,
@@ -3150,6 +3151,47 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `self_constructor_from_outer_item` lint detects cases where the `Self` constructor
+    /// was silently allowed due to a bug in the resolver, and which may produce surprising
+    /// and unintended behavior.
+    ///
+    /// Using a `Self` type alias from an outer item was never intended, but was silently allowed.
+    /// This is deprecated -- and is a hard error when the `Self` type alias references generics
+    /// that are not in scope.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(self_constructor_from_outer_item)]
+    ///
+    /// struct S0(usize);
+    ///
+    /// impl S0 {
+    ///     fn foo() {
+    ///         const C: S0 = Self(0);
+    ///         fn bar() -> S0 {
+    ///             Self(0)
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The `Self` type alias should not be reachable because nested items are not associated with
+    /// the scope of the parameters from the parent item.
+    pub SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
+    Warn,
+    "detect unsupported use of `Self` from outer item",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reference: "issue #124186 <https://github.com/rust-lang/rust/issues/124186>",
+    };
+}
+
+declare_lint! {
     /// The `semicolon_in_expressions_from_macros` lint detects trailing semicolons
     /// in macro bodies when the macro is invoked in expression position.
     /// This was previous accepted, but is being phased out.
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 870e4865aea..1c4462fc1dc 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -245,20 +245,6 @@ impl<'tcx> Generics {
         }
     }
 
-    /// Returns the `GenericParamDef` with the given index if available.
-    pub fn opt_param_at(
-        &'tcx self,
-        param_index: usize,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<&'tcx GenericParamDef> {
-        if let Some(index) = param_index.checked_sub(self.parent_count) {
-            self.own_params.get(index)
-        } else {
-            tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
-                .opt_param_at(param_index, tcx)
-        }
-    }
-
     pub fn params_to(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx [GenericParamDef] {
         if let Some(index) = param_index.checked_sub(self.parent_count) {
             &self.own_params[..index]
@@ -290,20 +276,6 @@ impl<'tcx> Generics {
         }
     }
 
-    /// Returns the `GenericParamDef` associated with this `ParamTy` if it belongs to this
-    /// `Generics`.
-    pub fn opt_type_param(
-        &'tcx self,
-        param: ParamTy,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<&'tcx GenericParamDef> {
-        let param = self.opt_param_at(param.index as usize, tcx)?;
-        match param.kind {
-            GenericParamDefKind::Type { .. } => Some(param),
-            _ => None,
-        }
-    }
-
     /// Returns the `GenericParamDef` associated with this `ParamConst`.
     pub fn const_param(&'tcx self, param: ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
         let param = self.param_at(param.index as usize, tcx);
diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml
index bd0a54ef363..f864a13a31b 100644
--- a/compiler/rustc_mir_transform/Cargo.toml
+++ b/compiler/rustc_mir_transform/Cargo.toml
@@ -16,6 +16,7 @@ rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
+rustc_infer = { path = "../rustc_infer" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_mir_build = { path = "../rustc_mir_build" }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 401056cd496..fe2237dd2e9 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1,7 +1,6 @@
 //! Inlining pass for MIR functions
 use crate::deref_separator::deref_finder;
 use rustc_attr::InlineAttr;
-use rustc_const_eval::transform::validate::validate_types;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
@@ -21,6 +20,7 @@ use rustc_target::spec::abi::Abi;
 use crate::cost_checker::CostChecker;
 use crate::simplify::simplify_cfg;
 use crate::util;
+use crate::validate::validate_types;
 use std::iter;
 use std::ops::{Range, RangeFrom};
 
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 9af48f0bad2..e4670633914 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -109,9 +109,9 @@ mod simplify_comparison_integral;
 mod sroa;
 mod unreachable_enum_branching;
 mod unreachable_prop;
+mod validate;
 
-use rustc_const_eval::transform::check_consts::{self, ConstCx};
-use rustc_const_eval::transform::validate;
+use rustc_const_eval::check_consts::{self, ConstCx};
 use rustc_mir_dataflow::rustc_peek;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 34aa31baab7..e37f90ae7f4 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -30,7 +30,7 @@ use std::assert_matches::assert_matches;
 use std::cell::Cell;
 use std::{cmp, iter, mem};
 
-use rustc_const_eval::transform::check_consts::{qualifs, ConstCx};
+use rustc_const_eval::check_consts::{qualifs, ConstCx};
 
 /// A `MirPass` for promotion.
 ///
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 3a2b2c5f300..66cc65de647 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -685,6 +685,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         check_equal(self, location, *f_ty);
                     }
                     ty::Adt(adt_def, args) => {
+                        // see <https://github.com/rust-lang/rust/blob/7601adcc764d42c9f2984082b49948af652df986/compiler/rustc_middle/src/ty/layout.rs#L861-L864>
+                        if Some(adt_def.did()) == self.tcx.lang_items().dyn_metadata() {
+                            self.fail(
+                                location,
+                                format!("You can't project to field {f:?} of `DynMetadata` because \
+                                         layout is weird and thinks it doesn't have fields."),
+                            );
+                        }
+
                         let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
                         let Some(field) = adt_def.variant(var).fields.get(f) else {
                             fail_out_of_bounds(self, location);
diff --git a/library/core/benches/str/debug.rs b/library/core/benches/str/debug.rs
index 7c72228f0fb..cb91169eed8 100644
--- a/library/core/benches/str/debug.rs
+++ b/library/core/benches/str/debug.rs
@@ -44,7 +44,7 @@ fn ascii_escapes(b: &mut Bencher) {
     assert_fmt(
         s,
         r#""some\tmore\tascii\ttext\nthis time with some \"escapes\", also 64 byte""#,
-        21,
+        15,
     );
     b.iter(|| {
         black_box(format!("{:?}", black_box(s)));
@@ -72,7 +72,7 @@ fn mostly_unicode(b: &mut Bencher) {
 #[bench]
 fn mixed(b: &mut Bencher) {
     let s = "\"❤️\"\n\"hűha ez betű\"\n\"кириллических букв\".";
-    assert_fmt(s, r#""\"❤\u{fe0f}\"\n\"hűha ez betű\"\n\"кириллических букв\".""#, 36);
+    assert_fmt(s, r#""\"❤\u{fe0f}\"\n\"hűha ez betű\"\n\"кириллических букв\".""#, 21);
     b.iter(|| {
         black_box(format!("{:?}", black_box(s)));
     });
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index fc6022ab753..f3f757ce69d 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -898,6 +898,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(2.clamp(-2, 1), 1);
     /// ```
     #[must_use]
+    #[inline]
     #[stable(feature = "clamp", since = "1.50.0")]
     fn clamp(self, min: Self, max: Self) -> Self
     where
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 60a27863413..1324fb6e056 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2402,23 +2402,47 @@ impl Display for bool {
 impl Debug for str {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         f.write_char('"')?;
-        let mut from = 0;
-        for (i, c) in self.char_indices() {
-            let esc = c.escape_debug_ext(EscapeDebugExtArgs {
-                escape_grapheme_extended: true,
-                escape_single_quote: false,
-                escape_double_quote: true,
-            });
-            // If char needs escaping, flush backlog so far and write, else skip
-            if esc.len() != 1 {
-                f.write_str(&self[from..i])?;
-                for c in esc {
-                    f.write_char(c)?;
+
+        // substring we know is printable
+        let mut printable_range = 0..0;
+
+        fn needs_escape(b: u8) -> bool {
+            b > 0x7E || b < 0x20 || b == b'\\' || b == b'"'
+        }
+
+        // the loop here first skips over runs of printable ASCII as a fast path.
+        // other chars (unicode, or ASCII that needs escaping) are then handled per-`char`.
+        let mut rest = self;
+        while rest.len() > 0 {
+            let Some(non_printable_start) = rest.as_bytes().iter().position(|&b| needs_escape(b))
+            else {
+                printable_range.end += rest.len();
+                break;
+            };
+
+            printable_range.end += non_printable_start;
+            // SAFETY: the position was derived from an iterator, so is known to be within bounds, and at a char boundary
+            rest = unsafe { rest.get_unchecked(non_printable_start..) };
+
+            let mut chars = rest.chars();
+            if let Some(c) = chars.next() {
+                let esc = c.escape_debug_ext(EscapeDebugExtArgs {
+                    escape_grapheme_extended: true,
+                    escape_single_quote: false,
+                    escape_double_quote: true,
+                });
+                if esc.len() != 1 {
+                    f.write_str(&self[printable_range.clone()])?;
+                    Display::fmt(&esc, f)?;
+                    printable_range.start = printable_range.end + c.len_utf8();
                 }
-                from = i + c.len_utf8();
+                printable_range.end += c.len_utf8();
             }
+            rest = chars.as_str();
         }
-        f.write_str(&self[from..])?;
+
+        f.write_str(&self[printable_range])?;
+
         f.write_char('"')
     }
 }
@@ -2434,13 +2458,12 @@ impl Display for str {
 impl Debug for char {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
         f.write_char('\'')?;
-        for c in self.escape_debug_ext(EscapeDebugExtArgs {
+        let esc = self.escape_debug_ext(EscapeDebugExtArgs {
             escape_grapheme_extended: true,
             escape_single_quote: true,
             escape_double_quote: false,
-        }) {
-            f.write_char(c)?
-        }
+        });
+        Display::fmt(&esc, f)?;
         f.write_char('\'')
     }
 }
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index d1be534eaf0..820f6b2cddc 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -152,7 +152,7 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn simd_fabs<T>(x: T) -> T;
 
-    /// Elementwise minimum of a vector.
+    /// Elementwise minimum of two vectors.
     ///
     /// `T` must be a vector of floating-point primitive types.
     ///
@@ -160,7 +160,7 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn simd_fmin<T>(x: T, y: T) -> T;
 
-    /// Elementwise maximum of a vector.
+    /// Elementwise maximum of two vectors.
     ///
     /// `T` must be a vector of floating-point primitive types.
     ///
@@ -387,7 +387,7 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
 
-    /// Add elements within a vector in arbitrary order. May also be re-associated with
+    /// Multiply elements within a vector in arbitrary order. May also be re-associated with
     /// unordered additions on the inputs/outputs.
     ///
     /// `T` must be a vector of integer or floating-point primitive types.
@@ -405,7 +405,7 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn simd_reduce_all<T>(x: T) -> bool;
 
-    /// Check if all mask values are true.
+    /// Check if any mask value is true.
     ///
     /// `T` must be a vector of integer primitive types.
     ///
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index eb815b6d822..e501970b580 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -178,8 +178,8 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
 /// compare equal (since identical vtables can be deduplicated within a codegen unit).
 #[lang = "dyn_metadata"]
 pub struct DynMetadata<Dyn: ?Sized> {
-    vtable_ptr: &'static VTable,
-    phantom: crate::marker::PhantomData<Dyn>,
+    _vtable_ptr: &'static VTable,
+    _phantom: crate::marker::PhantomData<Dyn>,
 }
 
 extern "C" {
@@ -191,6 +191,17 @@ extern "C" {
 }
 
 impl<Dyn: ?Sized> DynMetadata<Dyn> {
+    /// One of the things that rustc_middle does with this being a lang item is
+    /// give it `FieldsShape::Primitive`, which means that as far as codegen can
+    /// tell, it *is* a reference, and thus doesn't have any fields.
+    /// That means we can't use field access, and have to transmute it instead.
+    #[inline]
+    fn vtable_ptr(self) -> *const VTable {
+        // SAFETY: this layout assumption is hard-coded into the compiler.
+        // If it's somehow not a size match, the transmute will error.
+        unsafe { crate::mem::transmute::<Self, &'static VTable>(self) }
+    }
+
     /// Returns the size of the type associated with this vtable.
     #[inline]
     pub fn size_of(self) -> usize {
@@ -199,7 +210,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
         // `Send` part!
         // SAFETY: DynMetadata always contains a valid vtable pointer
         return unsafe {
-            crate::intrinsics::vtable_size(self.vtable_ptr as *const VTable as *const ())
+            crate::intrinsics::vtable_size(self.vtable_ptr() as *const ())
         };
     }
 
@@ -208,7 +219,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
     pub fn align_of(self) -> usize {
         // SAFETY: DynMetadata always contains a valid vtable pointer
         return unsafe {
-            crate::intrinsics::vtable_align(self.vtable_ptr as *const VTable as *const ())
+            crate::intrinsics::vtable_align(self.vtable_ptr() as *const ())
         };
     }
 
@@ -226,7 +237,7 @@ unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
 
 impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("DynMetadata").field(&(self.vtable_ptr as *const VTable)).finish()
+        f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish()
     }
 }
 
@@ -248,7 +259,7 @@ impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
 impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
-        crate::ptr::eq::<VTable>(self.vtable_ptr, other.vtable_ptr)
+        crate::ptr::eq::<VTable>(self.vtable_ptr(), other.vtable_ptr())
     }
 }
 
@@ -256,7 +267,7 @@ impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
     #[inline]
     #[allow(ambiguous_wide_pointer_comparisons)]
     fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
-        (self.vtable_ptr as *const VTable).cmp(&(other.vtable_ptr as *const VTable))
+        <*const VTable>::cmp(&self.vtable_ptr(), &other.vtable_ptr())
     }
 }
 
@@ -270,6 +281,6 @@ impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
 impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {
     #[inline]
     fn hash<H: Hasher>(&self, hasher: &mut H) {
-        crate::ptr::hash::<VTable, _>(self.vtable_ptr, hasher)
+        crate::ptr::hash::<VTable, _>(self.vtable_ptr(), hasher)
     }
 }
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index bbd1d840e92..8f70cefc601 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -9,8 +9,6 @@ pub mod cmath;
 pub mod os_str;
 pub mod path;
 pub mod sync;
-#[allow(dead_code)]
-#[allow(unused_imports)]
 pub mod thread_local;
 
 // FIXME(117276): remove this, move feature implementations into individual
diff --git a/library/std/src/sys/thread_local/fast_local/lazy.rs b/library/std/src/sys/thread_local/fast_local/lazy.rs
index 14371768d30..c2e9a171454 100644
--- a/library/std/src/sys/thread_local/fast_local/lazy.rs
+++ b/library/std/src/sys/thread_local/fast_local/lazy.rs
@@ -1,6 +1,5 @@
 use crate::cell::UnsafeCell;
 use crate::hint::unreachable_unchecked;
-use crate::mem::forget;
 use crate::ptr;
 use crate::sys::thread_local::abort_on_dtor_unwind;
 use crate::sys::thread_local_dtor::register_dtor;
diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs
index 36f6f907e72..0a78a1a1cf0 100644
--- a/library/std/src/sys/thread_local/mod.rs
+++ b/library/std/src/sys/thread_local/mod.rs
@@ -1,4 +1,5 @@
 #![unstable(feature = "thread_local_internals", reason = "should not be necessary", issue = "none")]
+#![cfg_attr(test, allow(unused))]
 
 // There are three thread-local implementations: "static", "fast", "OS".
 // The "OS" thread local key type is accessed via platform-specific API calls and is slow, while the
@@ -24,94 +25,12 @@ cfg_if::cfg_if! {
     }
 }
 
-// Not used by the fast-local TLS anymore.
-// FIXME(#110897): remove this.
-#[allow(unused)]
-mod lazy {
-    use crate::cell::UnsafeCell;
-    use crate::hint;
-    use crate::mem;
-
-    pub struct LazyKeyInner<T> {
-        inner: UnsafeCell<Option<T>>,
-    }
-
-    impl<T> LazyKeyInner<T> {
-        pub const fn new() -> LazyKeyInner<T> {
-            LazyKeyInner { inner: UnsafeCell::new(None) }
-        }
-
-        pub unsafe fn get(&self) -> Option<&'static T> {
-            // SAFETY: The caller must ensure no reference is ever handed out to
-            // the inner cell nor mutable reference to the Option<T> inside said
-            // cell. This make it safe to hand a reference, though the lifetime
-            // of 'static is itself unsafe, making the get method unsafe.
-            unsafe { (*self.inner.get()).as_ref() }
-        }
-
-        /// The caller must ensure that no reference is active: this method
-        /// needs unique access.
-        pub unsafe fn initialize<F: FnOnce() -> T>(&self, init: F) -> &'static T {
-            // Execute the initialization up front, *then* move it into our slot,
-            // just in case initialization fails.
-            let value = init();
-            let ptr = self.inner.get();
-
-            // SAFETY:
-            //
-            // note that this can in theory just be `*ptr = Some(value)`, but due to
-            // the compiler will currently codegen that pattern with something like:
-            //
-            //      ptr::drop_in_place(ptr)
-            //      ptr::write(ptr, Some(value))
-            //
-            // Due to this pattern it's possible for the destructor of the value in
-            // `ptr` (e.g., if this is being recursively initialized) to re-access
-            // TLS, in which case there will be a `&` and `&mut` pointer to the same
-            // value (an aliasing violation). To avoid setting the "I'm running a
-            // destructor" flag we just use `mem::replace` which should sequence the
-            // operations a little differently and make this safe to call.
-            //
-            // The precondition also ensures that we are the only one accessing
-            // `self` at the moment so replacing is fine.
-            unsafe {
-                let _ = mem::replace(&mut *ptr, Some(value));
-            }
-
-            // SAFETY: With the call to `mem::replace` it is guaranteed there is
-            // a `Some` behind `ptr`, not a `None` so `unreachable_unchecked`
-            // will never be reached.
-            unsafe {
-                // After storing `Some` we want to get a reference to the contents of
-                // what we just stored. While we could use `unwrap` here and it should
-                // always work it empirically doesn't seem to always get optimized away,
-                // which means that using something like `try_with` can pull in
-                // panicking code and cause a large size bloat.
-                match *ptr {
-                    Some(ref x) => x,
-                    None => hint::unreachable_unchecked(),
-                }
-            }
-        }
-
-        /// Watch out: unsynchronized internal mutability!
-        ///
-        /// # Safety
-        /// Causes UB if any reference to the value is used after this.
-        #[allow(unused)]
-        pub(crate) unsafe fn take(&self) -> Option<T> {
-            let mutable: *mut _ = UnsafeCell::get(&self.inner);
-            // SAFETY: That's the caller's problem.
-            unsafe { mutable.replace(None) }
-        }
-    }
-}
-
 /// Run a callback in a scenario which must not unwind (such as a `extern "C"
 /// fn` declared in a user crate). If the callback unwinds anyway, then
 /// `rtabort` with a message about thread local panicking on drop.
 #[inline]
-pub fn abort_on_dtor_unwind(f: impl FnOnce()) {
+#[allow(dead_code)]
+fn abort_on_dtor_unwind(f: impl FnOnce()) {
     // Using a guard like this is lower cost.
     let guard = DtorUnwindGuard;
     f();
diff --git a/library/std/src/sys/thread_local/os_local.rs b/library/std/src/sys/thread_local/os_local.rs
index 3edffd7e443..d6ddbb78a9c 100644
--- a/library/std/src/sys/thread_local/os_local.rs
+++ b/library/std/src/sys/thread_local/os_local.rs
@@ -1,7 +1,8 @@
-use super::lazy::LazyKeyInner;
+use super::abort_on_dtor_unwind;
 use crate::cell::Cell;
-use crate::sys_common::thread_local_key::StaticKey as OsStaticKey;
-use crate::{fmt, marker, panic, ptr};
+use crate::marker::PhantomData;
+use crate::ptr;
+use crate::sys_common::thread_local_key::StaticKey as OsKey;
 
 #[doc(hidden)]
 #[allow_internal_unstable(thread_local_internals)]
@@ -10,38 +11,9 @@ use crate::{fmt, marker, panic, ptr};
 #[rustc_macro_transparency = "semitransparent"]
 pub macro thread_local_inner {
     // used to generate the `LocalKey` value for const-initialized thread locals
-    (@key $t:ty, const $init:expr) => {{
-        #[inline]
-        #[deny(unsafe_op_in_unsafe_fn)]
-        unsafe fn __getit(
-            _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
-        ) -> $crate::option::Option<&'static $t> {
-            const INIT_EXPR: $t = $init;
-
-            // On platforms without `#[thread_local]` we fall back to the
-            // same implementation as below for os thread locals.
-            #[inline]
-            const fn __init() -> $t { INIT_EXPR }
-            static __KEY: $crate::thread::local_impl::Key<$t> =
-                $crate::thread::local_impl::Key::new();
-            unsafe {
-                __KEY.get(move || {
-                    if let $crate::option::Option::Some(init) = _init {
-                        if let $crate::option::Option::Some(value) = init.take() {
-                            return value;
-                        } else if $crate::cfg!(debug_assertions) {
-                            $crate::unreachable!("missing initial value");
-                        }
-                    }
-                    __init()
-                })
-            }
-        }
-
-        unsafe {
-            $crate::thread::LocalKey::new(__getit)
-        }
-    }},
+    (@key $t:ty, const $init:expr) => {
+        $crate::thread::local_impl::thread_local_inner!(@key $t, { const INIT_EXPR: $t = $init; INIT_EXPR })
+    },
 
     // used to generate the `LocalKey` value for `thread_local!`
     (@key $t:ty, $init:expr) => {
@@ -55,20 +27,11 @@ pub macro thread_local_inner {
             unsafe fn __getit(
                 init: $crate::option::Option<&mut $crate::option::Option<$t>>,
             ) -> $crate::option::Option<&'static $t> {
-                static __KEY: $crate::thread::local_impl::Key<$t> =
-                    $crate::thread::local_impl::Key::new();
+                use $crate::thread::local_impl::Key;
 
+                static __KEY: Key<$t> = Key::new();
                 unsafe {
-                    __KEY.get(move || {
-                        if let $crate::option::Option::Some(init) = init {
-                            if let $crate::option::Option::Some(value) = init.take() {
-                                return value;
-                            } else if $crate::cfg!(debug_assertions) {
-                                $crate::unreachable!("missing default value");
-                            }
-                        }
-                        __init()
-                    })
+                    __KEY.get(init, __init)
                 }
             }
 
@@ -85,78 +48,78 @@ pub macro thread_local_inner {
 
 /// Use a regular global static to store this key; the state provided will then be
 /// thread-local.
+#[allow(missing_debug_implementations)]
 pub struct Key<T> {
-    // OS-TLS key that we'll use to key off.
-    os: OsStaticKey,
-    marker: marker::PhantomData<Cell<T>>,
-}
-
-impl<T> fmt::Debug for Key<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Key").finish_non_exhaustive()
-    }
+    os: OsKey,
+    marker: PhantomData<Cell<T>>,
 }
 
 unsafe impl<T> Sync for Key<T> {}
 
 struct Value<T: 'static> {
-    inner: LazyKeyInner<T>,
+    value: T,
     key: &'static Key<T>,
 }
 
 impl<T: 'static> Key<T> {
     #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")]
     pub const fn new() -> Key<T> {
-        Key { os: OsStaticKey::new(Some(destroy_value::<T>)), marker: marker::PhantomData }
+        Key { os: OsKey::new(Some(destroy_value::<T>)), marker: PhantomData }
     }
 
-    /// It is a requirement for the caller to ensure that no mutable
-    /// reference is active when this method is called.
-    pub unsafe fn get(&'static self, init: impl FnOnce() -> T) -> Option<&'static T> {
-        // SAFETY: See the documentation for this method.
+    /// Get the value associated with this key, initializating it if necessary.
+    ///
+    /// # Safety
+    /// * the returned reference must not be used after recursive initialization
+    /// or thread destruction occurs.
+    pub unsafe fn get(
+        &'static self,
+        i: Option<&mut Option<T>>,
+        f: impl FnOnce() -> T,
+    ) -> Option<&'static T> {
+        // SAFETY: (FIXME: get should actually be safe)
         let ptr = unsafe { self.os.get() as *mut Value<T> };
         if ptr.addr() > 1 {
             // SAFETY: the check ensured the pointer is safe (its destructor
             // is not running) + it is coming from a trusted source (self).
-            if let Some(ref value) = unsafe { (*ptr).inner.get() } {
-                return Some(value);
-            }
+            unsafe { Some(&(*ptr).value) }
+        } else {
+            // SAFETY: At this point we are sure we have no value and so
+            // initializing (or trying to) is safe.
+            unsafe { self.try_initialize(ptr, i, f) }
         }
-        // SAFETY: At this point we are sure we have no value and so
-        // initializing (or trying to) is safe.
-        unsafe { self.try_initialize(init) }
     }
 
-    // `try_initialize` is only called once per os thread local variable,
-    // except in corner cases where thread_local dtors reference other
-    // thread_local's, or it is being recursively initialized.
-    unsafe fn try_initialize(&'static self, init: impl FnOnce() -> T) -> Option<&'static T> {
-        // SAFETY: No mutable references are ever handed out meaning getting
-        // the value is ok.
-        let ptr = unsafe { self.os.get() as *mut Value<T> };
+    unsafe fn try_initialize(
+        &'static self,
+        ptr: *mut Value<T>,
+        i: Option<&mut Option<T>>,
+        f: impl FnOnce() -> T,
+    ) -> Option<&'static T> {
         if ptr.addr() == 1 {
             // destructor is running
             return None;
         }
 
-        let ptr = if ptr.is_null() {
-            // If the lookup returned null, we haven't initialized our own
-            // local copy, so do that now.
-            let ptr = Box::into_raw(Box::new(Value { inner: LazyKeyInner::new(), key: self }));
-            // SAFETY: At this point we are sure there is no value inside
-            // ptr so setting it will not affect anyone else.
-            unsafe {
-                self.os.set(ptr as *mut u8);
-            }
-            ptr
-        } else {
-            // recursive initialization
-            ptr
-        };
+        let value = i.and_then(Option::take).unwrap_or_else(f);
+        let ptr = Box::into_raw(Box::new(Value { value, key: self }));
+        // SAFETY: (FIXME: get should actually be safe)
+        let old = unsafe { self.os.get() as *mut Value<T> };
+        // SAFETY: `ptr` is a correct pointer that can be destroyed by the key destructor.
+        unsafe {
+            self.os.set(ptr as *mut u8);
+        }
+        if !old.is_null() {
+            // If the variable was recursively initialized, drop the old value.
+            // SAFETY: We cannot be inside a `LocalKey::with` scope, as the
+            // initializer has already returned and the next scope only starts
+            // after we return the pointer. Therefore, there can be no references
+            // to the old value.
+            drop(unsafe { Box::from_raw(old) });
+        }
 
-        // SAFETY: ptr has been ensured as non-NUL just above an so can be
-        // dereferenced safely.
-        unsafe { Some((*ptr).inner.initialize(init)) }
+        // SAFETY: We just created this value above.
+        unsafe { Some(&(*ptr).value) }
     }
 }
 
@@ -170,16 +133,11 @@ unsafe extern "C" fn destroy_value<T: 'static>(ptr: *mut u8) {
     //
     // Note that to prevent an infinite loop we reset it back to null right
     // before we return from the destructor ourselves.
-    //
-    // Wrap the call in a catch to ensure unwinding is caught in the event
-    // a panic takes place in a destructor.
-    if let Err(_) = panic::catch_unwind(|| unsafe {
-        let ptr = Box::from_raw(ptr as *mut Value<T>);
+    abort_on_dtor_unwind(|| {
+        let ptr = unsafe { Box::from_raw(ptr as *mut Value<T>) };
         let key = ptr.key;
-        key.os.set(ptr::without_provenance_mut(1));
+        unsafe { key.os.set(ptr::without_provenance_mut(1)) };
         drop(ptr);
-        key.os.set(ptr::null_mut());
-    }) {
-        rtabort!("thread local panicked on drop");
-    }
+        unsafe { key.os.set(ptr::null_mut()) };
+    });
 }
diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs
index 9a5dc351f6d..64ca13c0d4e 100644
--- a/library/test/src/bench.rs
+++ b/library/test/src/bench.rs
@@ -98,7 +98,7 @@ fn fmt_thousands_sep(mut n: f64, sep: char) -> String {
                 (0, true) => write!(output, "{:06.2}", n / base as f64).unwrap(),
                 (0, false) => write!(output, "{:.2}", n / base as f64).unwrap(),
                 (_, true) => write!(output, "{:03}", n as usize / base).unwrap(),
-                _ => write!(output,  "{}", n as usize / base).unwrap()
+                _ => write!(output, "{}", n as usize / base).unwrap(),
             }
             if pow != 0 {
                 output.push(sep);
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index 077db44ae54..fb3c8627043 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -6,7 +6,7 @@ and some of the technical details of the build system.
 Note that this README only covers internal information, not how to use the tool.
 Please check [bootstrapping dev guide][bootstrapping-dev-guide] for further information.
 
-[bootstrapping-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html
+[bootstrapping-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/bootstrapping/intro.html
 
 ## Introduction
 
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 9710365ef11..276fd0b11d6 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -60,7 +60,14 @@ fn check_cli<const N: usize>(paths: [&str; N]) {
 macro_rules! std {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Std::new(
-            Compiler { host: TargetSelection::from_user(concat!(stringify!($host), "-", stringify!($host))), stage: $stage },
+            Compiler {
+                host: TargetSelection::from_user(concat!(
+                    stringify!($host),
+                    "-",
+                    stringify!($host)
+                )),
+                stage: $stage,
+            },
             TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
         )
     };
@@ -83,7 +90,14 @@ macro_rules! doc_std {
 macro_rules! rustc {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Rustc::new(
-            Compiler { host: TargetSelection::from_user(concat!(stringify!($host), "-", stringify!($host))), stage: $stage },
+            Compiler {
+                host: TargetSelection::from_user(concat!(
+                    stringify!($host),
+                    "-",
+                    stringify!($host)
+                )),
+                stage: $stage,
+            },
             TargetSelection::from_user(concat!(stringify!($target), "-", stringify!($target))),
         )
     };
@@ -141,10 +155,14 @@ fn check_missing_paths_for_x_test_tests() {
 
         // Skip if not a test directory.
         if path.ends_with("tests/auxiliary") || !path.is_dir() {
-            continue
+            continue;
         }
 
-        assert!(tests_remap_paths.iter().any(|item| path.ends_with(*item)), "{} is missing in PATH_REMAP tests list.", path.display());
+        assert!(
+            tests_remap_paths.iter().any(|item| path.ends_with(*item)),
+            "{} is missing in PATH_REMAP tests list.",
+            path.display()
+        );
     }
 }
 
@@ -185,7 +203,8 @@ fn alias_and_path_for_library() {
         &[std!(A => A, stage = 0), std!(A => A, stage = 1)]
     );
 
-    let mut cache = run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"]));
+    let mut cache =
+        run_build(&["library".into(), "core".into()], configure("doc", &["A-A"], &["A-A"]));
     assert_eq!(first(cache.all::<doc::Std>()), &[doc_std!(A => A, stage = 0)]);
 }
 
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 9c3df6fa9e3..8ffa97ab78b 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -199,11 +199,15 @@ than building it.
         if !["A-A", "B-B", "C-C"].contains(&target_str.as_str()) {
             let mut has_target = false;
 
-            let missing_targets_hashset: HashSet<_> = STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect();
-            let duplicated_targets: Vec<_> = stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
+            let missing_targets_hashset: HashSet<_> =
+                STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect();
+            let duplicated_targets: Vec<_> =
+                stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
 
             if !duplicated_targets.is_empty() {
-                println!("Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list.");
+                println!(
+                    "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
+                );
                 for duplicated_target in duplicated_targets {
                     println!("  {duplicated_target}");
                 }
diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs
index 6a4e86eb1df..2abda5d3ebf 100644
--- a/src/tools/build_helper/src/lib.rs
+++ b/src/tools/build_helper/src/lib.rs
@@ -1,5 +1,5 @@
 pub mod ci;
 pub mod git;
 pub mod metrics;
-pub mod util;
 pub mod stage0_parser;
+pub mod util;
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 8ee7d87acb3..81e94725a70 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -6,7 +6,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use hir::LangItem;
 use rustc_attr::StableSince;
-use rustc_const_eval::transform::check_consts::ConstCx;
+use rustc_const_eval::check_consts::ConstCx;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index d3840775da9..aa06a0dbcdc 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-78dd504f2fd87c0cfabff7d9174253411caf2f80
+21e6de7eb64c09102de3f100420a09edc1a2a8d7
diff --git a/src/tools/miri/tests/panic/mir-validation.stderr b/src/tools/miri/tests/panic/mir-validation.stderr
index d158c996dc3..d5dd53d7b4e 100644
--- a/src/tools/miri/tests/panic/mir-validation.stderr
+++ b/src/tools/miri/tests/panic/mir-validation.stderr
@@ -1,4 +1,4 @@
-thread 'rustc' panicked at compiler/rustc_const_eval/src/transform/validate.rs:LL:CC:
+thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
 broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]:
 (*(_2.0: *mut i32)), has deref at the wrong place
 stack backtrace:
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index ad900ce0386..9a6ae18abea 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -228,7 +228,6 @@ run-make/rmeta-preferred/Makefile
 run-make/rustc-macro-dep-files/Makefile
 run-make/rustdoc-io-error/Makefile
 run-make/rustdoc-verify-output-files/Makefile
-run-make/rustdoc-with-output-option/Makefile
 run-make/sanitizer-cdylib-link/Makefile
 run-make/sanitizer-dylib-link/Makefile
 run-make/sanitizer-staticlib-link/Makefile
diff --git a/tests/crashes/118403.rs b/tests/crashes/118403.rs
deleted file mode 100644
index 21ab15f9ffd..00000000000
--- a/tests/crashes/118403.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #118403
-#![feature(generic_const_exprs)]
-pub struct X<const N: usize> {}
-impl<const Z: usize> X<Z> {
-    pub fn y<'a, U: 'a>(&'a self) -> impl Iterator<Item = impl Iterator<Item = [u8; Z]> + '_> {
-        (0..1).map(move |_| (0..1).map(move |_| loop {}))
-    }
-}
diff --git a/tests/crashes/121574-2.rs b/tests/crashes/121574-2.rs
deleted file mode 100644
index a08f3f06397..00000000000
--- a/tests/crashes/121574-2.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #121574
-#![feature(generic_const_exprs)]
-pub struct DimName<const N: usize> {}
-impl<const Z: usize> X<Z> {
-    pub fn y<'a, U: 'a>(&'a self) -> impl Iterator<Item = impl Iterator<Item = [u8; Z]> + '_> {
-        "0".as_bytes(move |_| (0..1).map(move |_| loop {}))
-    }
-}
diff --git a/tests/crashes/121574.rs b/tests/crashes/121574.rs
deleted file mode 100644
index 53eec829c5f..00000000000
--- a/tests/crashes/121574.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #121574
-#![feature(generic_const_exprs)]
-
-impl<const Z: usize> X<Z> {
-    pub fn y<'a, U: 'a>(&'a self) -> impl Iterator<Item = impl Iterator<Item = [u8; Z]> + '_> {}
-}
diff --git a/tests/crashes/124833.rs b/tests/crashes/124833.rs
deleted file mode 100644
index f1c4847b544..00000000000
--- a/tests/crashes/124833.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: rust-lang/rust#124833
-#![feature(generic_const_items)]
-
-trait Trait {
-    const C<'a>: &'a str;
-}
-
-impl Trait for () {
-    const C<'a>:  = "C";
-}
diff --git a/tests/crashes/124891.rs b/tests/crashes/124891.rs
deleted file mode 100644
index 9b5892418c8..00000000000
--- a/tests/crashes/124891.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ known-bug: rust-lang/rust#124891
-
-type Tait = impl FnOnce() -> ();
-
-fn reify_as_tait() -> Thunk<Tait> {
-    Thunk::new(|cont| cont)
-}
-
-struct Thunk<F>(F);
-
-impl<F> Thunk<F> {
-    fn new(f: F)
-    where
-        F: ContFn,
-    {
-        todo!();
-    }
-}
-
-trait ContFn {}
-
-impl<F: FnOnce(Tait) -> ()> ContFn for F {}
diff --git a/tests/run-make/rustdoc-with-output-option/Makefile b/tests/run-make/rustdoc-with-output-option/Makefile
deleted file mode 100644
index d0a8205a8ee..00000000000
--- a/tests/run-make/rustdoc-with-output-option/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-include ../tools.mk
-
-OUTPUT_DIR := "$(TMPDIR)/rustdoc"
-
-all:
-	$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib --output $(OUTPUT_DIR)
-
-	$(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
diff --git a/tests/run-make/rustdoc-with-output-option/rmake.rs b/tests/run-make/rustdoc-with-output-option/rmake.rs
new file mode 100644
index 00000000000..1a009419273
--- /dev/null
+++ b/tests/run-make/rustdoc-with-output-option/rmake.rs
@@ -0,0 +1,16 @@
+use run_make_support::{htmldocck, rustdoc, tmp_dir};
+
+fn main() {
+    let out_dir = tmp_dir().join("rustdoc");
+
+    rustdoc()
+        .input("src/lib.rs")
+        .crate_name("foobar")
+        .crate_type("lib")
+        // This is intentionally using `--output` option flag and not the `output()` method.
+        .arg("--output")
+        .arg(&out_dir)
+        .run();
+
+    assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success());
+}
diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs
new file mode 100644
index 00000000000..1c2b7d02155
--- /dev/null
+++ b/tests/rustdoc-json/keyword_private.rs
@@ -0,0 +1,20 @@
+// Ensure keyword docs are present with --document-private-items
+
+//@ compile-flags: --document-private-items
+#![feature(rustdoc_internals)]
+
+// @!has "$.index[*][?(@.name=='match')]"
+// @has  "$.index[*][?(@.name=='foo')]"
+// @is   "$.index[*][?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]'
+// @is   "$.index[*][?(@.name=='foo')].docs" '"this is a test!"'
+#[doc(keyword = "match")]
+/// this is a test!
+pub mod foo {}
+
+// @!has "$.index[*][?(@.name=='hello')]"
+// @has "$.index[*][?(@.name=='bar')]"
+// @is   "$.index[*][?(@.name=='bar')].attrs" '["#[doc(keyword = \"hello\")]"]'
+// @is   "$.index[*][?(@.name=='bar')].docs" '"hello"'
+#[doc(keyword = "hello")]
+/// hello
+mod bar {}
diff --git a/tests/ui/binop/nested-assignment-may-be-deref.rs b/tests/ui/binop/nested-assignment-may-be-deref.rs
new file mode 100644
index 00000000000..f675ab2e918
--- /dev/null
+++ b/tests/ui/binop/nested-assignment-may-be-deref.rs
@@ -0,0 +1,14 @@
+pub fn bad(x: &mut bool) {
+    if true
+    *x = true {}
+    //~^ ERROR cannot multiply `bool` by `&mut bool`
+}
+
+pub fn bad2(x: &mut bool) {
+    let y: bool;
+    y = true
+    *x = true;
+    //~^ ERROR cannot multiply `bool` by `&mut bool`
+}
+
+fn main() {}
diff --git a/tests/ui/binop/nested-assignment-may-be-deref.stderr b/tests/ui/binop/nested-assignment-may-be-deref.stderr
new file mode 100644
index 00000000000..95b2db2b26c
--- /dev/null
+++ b/tests/ui/binop/nested-assignment-may-be-deref.stderr
@@ -0,0 +1,29 @@
+error[E0369]: cannot multiply `bool` by `&mut bool`
+  --> $DIR/nested-assignment-may-be-deref.rs:3:5
+   |
+LL |     if true
+   |        ---- bool
+LL |     *x = true {}
+   |     ^- &mut bool
+   |
+help: you might have meant to write a semicolon here
+   |
+LL |     if true;
+   |            +
+
+error[E0369]: cannot multiply `bool` by `&mut bool`
+  --> $DIR/nested-assignment-may-be-deref.rs:10:5
+   |
+LL |     y = true
+   |         ---- bool
+LL |     *x = true;
+   |     ^- &mut bool
+   |
+help: you might have meant to write a semicolon here
+   |
+LL |     y = true;
+   |             +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs
new file mode 100644
index 00000000000..e48d559aa32
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+#![feature(generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete and may not be safe to use
+
+pub fn y<'a, U: 'a>() -> impl IntoIterator<Item = impl IntoIterator<Item = [u8; { 1 + 2 }]> + 'a> {
+    [[[1, 2, 3]]]
+}
+// Make sure that the `predicates_of` for `{ 1 + 2 }` don't mention the duplicated lifetimes of
+// the *outer* iterator. Whether they should mention the duplicated lifetimes of the *inner*
+// iterator are another question, but not really something we need to answer immediately.
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr
new file mode 100644
index 00000000000..faaede13e6b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/double-opaque-parent-predicates.stderr
@@ -0,0 +1,11 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/double-opaque-parent-predicates.rs:3:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs
new file mode 100644
index 00000000000..93160f0b575
--- /dev/null
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs
@@ -0,0 +1,21 @@
+// Ensure that we properly deal with missing/placeholder types inside GACs.
+// issue: rust-lang/rust#124833
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+trait Trait {
+    const K<T>: T;
+    const Q<'a>: &'a str;
+}
+
+impl Trait for () {
+    const K<T> = ();
+    //~^ ERROR missing type for `const` item
+    //~| ERROR mismatched types
+    //~| ERROR mismatched types
+    const Q = "";
+    //~^ ERROR missing type for `const` item
+    //~| ERROR lifetime parameters or bounds on const `Q` do not match the trait declaration
+}
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr
new file mode 100644
index 00000000000..6f35c0958d4
--- /dev/null
+++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr
@@ -0,0 +1,48 @@
+error[E0308]: mismatched types
+  --> $DIR/assoc-const-missing-type.rs:12:18
+   |
+LL |     const K<T> = ();
+   |             -    ^^ expected type parameter `T`, found `()`
+   |             |
+   |             expected this type parameter
+   |
+   = note: expected type parameter `T`
+                   found unit type `()`
+
+error: missing type for `const` item
+  --> $DIR/assoc-const-missing-type.rs:12:15
+   |
+LL |     const K<T> = ();
+   |               ^ help: provide a type for the associated constant: `()`
+
+error[E0195]: lifetime parameters or bounds on const `Q` do not match the trait declaration
+  --> $DIR/assoc-const-missing-type.rs:16:12
+   |
+LL |     const Q<'a>: &'a str;
+   |            ---- lifetimes in impl do not match this const in trait
+...
+LL |     const Q = "";
+   |            ^ lifetimes do not match const in trait
+
+error: missing type for `const` item
+  --> $DIR/assoc-const-missing-type.rs:16:12
+   |
+LL |     const Q = "";
+   |            ^ help: provide a type for the associated constant: `: &str`
+
+error[E0308]: mismatched types
+  --> $DIR/assoc-const-missing-type.rs:12:18
+   |
+LL |     const K<T> = ();
+   |             -    ^^ expected type parameter `T`, found `()`
+   |             |
+   |             expected this type parameter
+   |
+   = note: expected type parameter `T`
+                   found unit type `()`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0195, E0308.
+For more information about an error, try `rustc --explain E0195`.
diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs
new file mode 100644
index 00000000000..65331894725
--- /dev/null
+++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.rs
@@ -0,0 +1,59 @@
+//! This test checks that we allow subtyping predicates that contain opaque types.
+//! No hidden types are being constrained in the subtyping predicate, but type and
+//! lifetime variables get subtyped in the generic parameter list of the opaque.
+
+use std::iter;
+
+mod either {
+    pub enum Either<L, R> {
+        Left(L),
+        Right(R),
+    }
+
+    impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> {
+        type Item = L::Item;
+        fn next(&mut self) -> Option<Self::Item> {
+            todo!()
+        }
+    }
+    pub use self::Either::{Left, Right};
+}
+
+pub enum BabeConsensusLogRef<'a> {
+    NextEpochData(BabeNextEpochRef<'a>),
+    NextConfigData,
+}
+
+impl<'a> BabeConsensusLogRef<'a> {
+    pub fn scale_encoding(
+        &self,
+    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
+        //~^ ERROR is not satisfied
+        //~| ERROR is not satisfied
+        //~| ERROR is not satisfied
+        match self {
+            BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left(
+                digest.scale_encoding().map(either::Left).map(either::Left),
+            )),
+            BabeConsensusLogRef::NextConfigData => either::Right(
+                // The Opaque type from ``scale_encoding` gets used opaquely here, while the `R`
+                // generic parameter of `Either` contains type variables that get subtyped and the
+                // opaque type contains lifetime variables that get subtyped.
+                iter::once(either::Right(either::Left([1])))
+                    .chain(std::iter::once([1]).map(either::Right).map(either::Right)),
+            ),
+        }
+    }
+}
+
+pub struct BabeNextEpochRef<'a>(&'a ());
+
+impl<'a> BabeNextEpochRef<'a> {
+    pub fn scale_encoding(
+        &self,
+    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
+        std::iter::once([1])
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr
new file mode 100644
index 00000000000..2f8c957c2c7
--- /dev/null
+++ b/tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied
+  --> $DIR/lazy_subtyping_of_opaques.rs:30:10
+   |
+LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>`
+
+error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied
+  --> $DIR/lazy_subtyping_of_opaques.rs:30:31
+   |
+LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
+
+error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied
+  --> $DIR/lazy_subtyping_of_opaques.rs:30:31
+   |
+LL |     ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/malformed/do-not-ice-on-note_and_explain.rs b/tests/ui/malformed/do-not-ice-on-note_and_explain.rs
index e65276fb738..be0b18a00d2 100644
--- a/tests/ui/malformed/do-not-ice-on-note_and_explain.rs
+++ b/tests/ui/malformed/do-not-ice-on-note_and_explain.rs
@@ -1,7 +1,12 @@
 struct A<B>(B);
-impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-//~^ ERROR the size for values of type `B` cannot be known at compilation time
-//~| ERROR the size for values of type `B` cannot be known at compilation time
-//~| ERROR mismatched types
-//~| ERROR mismatched types
-//~| ERROR `main` function not found in crate
+
+impl<B> A<B> {
+    fn d() {
+        fn d() {
+            Self(1)
+            //~^ ERROR can't reference `Self` constructor from outer item
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr
index 41d0f17366b..11a8c01e490 100644
--- a/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr
+++ b/tests/ui/malformed/do-not-ice-on-note_and_explain.stderr
@@ -1,79 +1,12 @@
-error[E0601]: `main` function not found in crate `do_not_ice_on_note_and_explain`
-  --> $DIR/do-not-ice-on-note_and_explain.rs:2:37
+error[E0401]: can't reference `Self` constructor from outer item
+  --> $DIR/do-not-ice-on-note_and_explain.rs:6:13
    |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-   |                                     ^ consider adding a `main` function to `$DIR/do-not-ice-on-note_and_explain.rs`
+LL | impl<B> A<B> {
+   | ------------ the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+...
+LL |             Self(1)
+   |             ^^^^ help: replace `Self` with the actual type: `A`
 
-error[E0277]: the size for values of type `B` cannot be known at compilation time
-  --> $DIR/do-not-ice-on-note_and_explain.rs:2:32
-   |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-   |      -                    ---- ^ doesn't have a size known at compile-time
-   |      |                    |
-   |      |                    required by a bound introduced by this call
-   |      this type parameter needs to be `Sized`
-   |
-note: required by a bound in `A`
-  --> $DIR/do-not-ice-on-note_and_explain.rs:1:10
-   |
-LL | struct A<B>(B);
-   |          ^ required by this bound in `A`
-
-error[E0308]: mismatched types
-  --> $DIR/do-not-ice-on-note_and_explain.rs:2:32
-   |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-   |                           ---- ^ expected type parameter `B`, found integer
-   |                           |
-   |                           arguments to this function are incorrect
-   |
-   = note: expected type parameter `B`
-                        found type `{integer}`
-note: tuple struct defined here
-  --> $DIR/do-not-ice-on-note_and_explain.rs:1:8
-   |
-LL | struct A<B>(B);
-   |        ^
-
-error[E0308]: mismatched types
-  --> $DIR/do-not-ice-on-note_and_explain.rs:2:27
-   |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-   |                           ^^^^^^^ expected `()`, found `A<B>`
-   |
-   = note: expected unit type `()`
-                 found struct `A<B>`
-help: consider using a semicolon here
-   |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1);}}}
-   |                                  +
-help: try adding a return type
-   |
-LL | impl<B>A<B>{fn d(){fn d() -> A<B>{Self(1)}}}
-   |                           +++++++
-
-error[E0277]: the size for values of type `B` cannot be known at compilation time
-  --> $DIR/do-not-ice-on-note_and_explain.rs:2:27
-   |
-LL | impl<B>A<B>{fn d(){fn d(){Self(1)}}}
-   |      -                    ^^^^^^^ doesn't have a size known at compile-time
-   |      |
-   |      this type parameter needs to be `Sized`
-   |
-note: required by an implicit `Sized` bound in `A`
-  --> $DIR/do-not-ice-on-note_and_explain.rs:1:10
-   |
-LL | struct A<B>(B);
-   |          ^ required by the implicit `Sized` requirement on this type parameter in `A`
-help: you could relax the implicit `Sized` bound on `B` if it were used through indirection like `&B` or `Box<B>`
-  --> $DIR/do-not-ice-on-note_and_explain.rs:1:10
-   |
-LL | struct A<B>(B);
-   |          ^  - ...if indirection were used here: `Box<B>`
-   |          |
-   |          this could be changed to `B: ?Sized`...
-
-error: aborting due to 5 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0308, E0601.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0401`.
diff --git a/tests/ui/self/self-ctor-nongeneric.rs b/tests/ui/self/self-ctor-nongeneric.rs
index 0594e87a0a4..c32cf9df694 100644
--- a/tests/ui/self/self-ctor-nongeneric.rs
+++ b/tests/ui/self/self-ctor-nongeneric.rs
@@ -6,8 +6,12 @@ struct S0(usize);
 impl S0 {
     fn foo() {
         const C: S0 = Self(0);
+        //~^ WARN can't reference `Self` constructor from outer item
+        //~| WARN this was previously accepted by the compiler but is being phased out
         fn bar() -> S0 {
             Self(0)
+            //~^ WARN can't reference `Self` constructor from outer item
+            //~| WARN this was previously accepted by the compiler but is being phased out
         }
     }
 }
diff --git a/tests/ui/self/self-ctor-nongeneric.stderr b/tests/ui/self/self-ctor-nongeneric.stderr
new file mode 100644
index 00000000000..6c03c6f3e38
--- /dev/null
+++ b/tests/ui/self/self-ctor-nongeneric.stderr
@@ -0,0 +1,27 @@
+warning: can't reference `Self` constructor from outer item
+  --> $DIR/self-ctor-nongeneric.rs:8:23
+   |
+LL | impl S0 {
+   | ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+LL |     fn foo() {
+LL |         const C: S0 = Self(0);
+   |                       ^^^^ help: replace `Self` with the actual type: `S0`
+   |
+   = 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 #124186 <https://github.com/rust-lang/rust/issues/124186>
+   = note: `#[warn(self_constructor_from_outer_item)]` on by default
+
+warning: can't reference `Self` constructor from outer item
+  --> $DIR/self-ctor-nongeneric.rs:12:13
+   |
+LL | impl S0 {
+   | ------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+...
+LL |             Self(0)
+   |             ^^^^ help: replace `Self` with the actual type: `S0`
+   |
+   = 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 #124186 <https://github.com/rust-lang/rust/issues/124186>
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/self/self-ctor.rs b/tests/ui/self/self-ctor.rs
new file mode 100644
index 00000000000..d166499f884
--- /dev/null
+++ b/tests/ui/self/self-ctor.rs
@@ -0,0 +1,14 @@
+struct S0<T>(T);
+
+impl<T> S0<T> {
+    fn foo() {
+        const C: S0<i32> = Self(0);
+        //~^ ERROR can't reference `Self` constructor from outer item
+        fn bar() -> S0<i32> {
+            Self(0)
+            //~^ ERROR can't reference `Self` constructor from outer item
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/self-ctor.stderr b/tests/ui/self/self-ctor.stderr
new file mode 100644
index 00000000000..0cb22baaa1a
--- /dev/null
+++ b/tests/ui/self/self-ctor.stderr
@@ -0,0 +1,21 @@
+error[E0401]: can't reference `Self` constructor from outer item
+  --> $DIR/self-ctor.rs:5:28
+   |
+LL | impl<T> S0<T> {
+   | ------------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+LL |     fn foo() {
+LL |         const C: S0<i32> = Self(0);
+   |                            ^^^^ help: replace `Self` with the actual type: `S0`
+
+error[E0401]: can't reference `Self` constructor from outer item
+  --> $DIR/self-ctor.rs:8:13
+   |
+LL | impl<T> S0<T> {
+   | ------------- the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
+...
+LL |             Self(0)
+   |             ^^^^ help: replace `Self` with the actual type: `S0`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0401`.
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
new file mode 100644
index 00000000000..72a90287e37
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs
@@ -0,0 +1,30 @@
+#![feature(type_alias_impl_trait)]
+
+//! This test used to ICE rust-lang/rust#124891
+//! because we added an assertion for catching cases where opaque types get
+//! registered during the processing of subtyping predicates.
+
+type Tait = impl FnOnce() -> ();
+
+fn reify_as_tait() -> Thunk<Tait> {
+    Thunk::new(|cont| cont)
+    //~^ ERROR: mismatched types
+    //~| ERROR: mismatched types
+}
+
+struct Thunk<F>(F);
+
+impl<F> Thunk<F> {
+    fn new(f: F)
+    where
+        F: ContFn,
+    {
+        todo!();
+    }
+}
+
+trait ContFn {}
+
+impl<F: FnOnce(Tait) -> ()> ContFn for F {}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
new file mode 100644
index 00000000000..5a35dc27446
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+  --> $DIR/lazy_subtyping_of_opaques.rs:10:23
+   |
+LL | type Tait = impl FnOnce() -> ();
+   |             ------------------- the found opaque type
+...
+LL |     Thunk::new(|cont| cont)
+   |                       ^^^^ expected `()`, found opaque type
+   |
+   = note: expected unit type `()`
+            found opaque type `Tait`
+
+error[E0308]: mismatched types
+  --> $DIR/lazy_subtyping_of_opaques.rs:10:5
+   |
+LL | fn reify_as_tait() -> Thunk<Tait> {
+   |                       ----------- expected `Thunk<_>` because of return type
+LL |     Thunk::new(|cont| cont)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()`
+   |
+   = note: expected struct `Thunk<_>`
+           found unit type `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/triagebot.toml b/triagebot.toml
index 95fa3befe60..7c58402b737 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -389,8 +389,11 @@ exclude_labels = [
 
 [autolabel."WG-trait-system-refactor"]
 trigger_files = [
+    "compiler/rustc_middle/src/traits/solve",
+    "compiler/rustc_next_trait_solver",
     "compiler/rustc_trait_selection/src/solve",
-    "compiler/rustc_middle/src/traits/solve"
+    "compiler/rustc_type_ir/src/solve",
+    "tests/ui/traits/next-solver",
 ]
 
 [autolabel."PG-exploit-mitigations"]