about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock10
-rw-r--r--compiler/rustc_ast/src/ast.rs65
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs61
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0502.md5
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs74
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs86
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs2
-rw-r--r--compiler/rustc_infer/Cargo.toml2
-rw-r--r--compiler/rustc_infer/src/infer/context.rs172
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs266
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs6
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs33
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs36
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs4
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs4
-rw-r--r--compiler/rustc_infer/src/traits/util.rs49
-rw-r--r--compiler/rustc_lint/src/context/diagnostics/check_cfg.rs18
-rw-r--r--compiler/rustc_middle/src/middle/dependency_format.rs6
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs11
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs13
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs25
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs7
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs12
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo.rs107
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs8
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs22
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs96
-rw-r--r--compiler/rustc_next_trait_solver/src/lib.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/relate.rs15
-rw-r--r--compiler/rustc_next_trait_solver/src/relate/combine.rs34
-rw-r--r--compiler/rustc_next_trait_solver/src/resolve.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs40
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs171
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs93
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs8
-rw-r--r--compiler/rustc_type_ir/src/interner.rs3
-rw-r--r--compiler/rustc_type_ir/src/lib.rs3
-rw-r--r--compiler/rustc_type_ir/src/outlives.rs228
-rw-r--r--library/core/src/default.rs1
-rw-r--r--library/core/src/fmt/mod.rs22
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/ptr/const_ptr.rs126
-rw-r--r--library/core/src/ptr/mut_ptr.rs126
-rw-r--r--library/core/src/ptr/non_null.rs131
-rw-r--r--library/core/src/range.rs494
-rw-r--r--library/core/src/range/iter.rs340
-rw-r--r--library/core/src/range/legacy.rs10
-rw-r--r--library/core/src/slice/index.rs124
-rw-r--r--library/core/src/str/traits.rs195
-rw-r--r--library/panic_unwind/src/lib.rs34
-rw-r--r--library/std/src/path.rs94
-rw-r--r--library/std/src/path/tests.rs74
-rw-r--r--library/std/src/sys/pal/windows/c.rs9
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt2
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs970
-rw-r--r--library/std/src/sys/pal/windows/c/windows_targets.rs24
-rw-r--r--library/std/src/sys/pal/windows/stdio.rs8
-rwxr-xr-xsrc/ci/docker/run.sh3
-rwxr-xr-xsrc/ci/github-actions/calculate-job-matrix.py14
-rw-r--r--src/librustdoc/html/static/js/search.js18
m---------src/llvm-project0
-rw-r--r--src/tools/generate-windows-sys/Cargo.toml2
-rw-r--r--src/tools/generate-windows-sys/src/main.rs1
-rw-r--r--src/tools/linkchecker/main.rs2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs16
-rw-r--r--src/tools/run-make-support/src/command.rs5
-rw-r--r--src/tools/run-make-support/src/lib.rs41
-rw-r--r--src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs8
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt9
-rw-r--r--src/tools/tidy/src/features.rs14
-rw-r--r--tests/crashes/126896.rs17
-rw-r--r--tests/crashes/126939.rs21
-rw-r--r--tests/crashes/126942.rs11
-rw-r--r--tests/crashes/126944.rs38
-rw-r--r--tests/crashes/126966.rs29
-rw-r--r--tests/crashes/126969.rs9
-rw-r--r--tests/crashes/126982.rs18
-rw-r--r--tests/crashes/127222.rs3
-rw-r--r--tests/crashes/127266.rs17
-rw-r--r--tests/crashes/127299.rs12
-rw-r--r--tests/crashes/127304.rs20
-rw-r--r--tests/crashes/127332.rs9
-rw-r--r--tests/run-make/include-bytes-deps/input.bin (renamed from tests/run-make/include_bytes_deps/input.bin)0
-rw-r--r--tests/run-make/include-bytes-deps/input.md (renamed from tests/run-make/include_bytes_deps/input.md)0
-rw-r--r--tests/run-make/include-bytes-deps/input.txt (renamed from tests/run-make/include_bytes_deps/input.txt)0
-rw-r--r--tests/run-make/include-bytes-deps/main.rs (renamed from tests/run-make/include_bytes_deps/main.rs)0
-rw-r--r--tests/run-make/include-bytes-deps/rmake.rs13
-rw-r--r--tests/run-make/include_bytes_deps/Makefile7
-rw-r--r--tests/run-make/issue-40535/Makefile13
-rw-r--r--tests/run-make/llvm-ident/rmake.rs2
-rw-r--r--tests/run-make/metadata-only-crate-no-ice/bar.rs (renamed from tests/run-make/issue-40535/bar.rs)0
-rw-r--r--tests/run-make/metadata-only-crate-no-ice/baz.rs (renamed from tests/run-make/issue-40535/baz.rs)0
-rw-r--r--tests/run-make/metadata-only-crate-no-ice/foo.rs (renamed from tests/run-make/issue-40535/foo.rs)0
-rw-r--r--tests/run-make/metadata-only-crate-no-ice/rmake.rs14
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/Makefile17
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/rmake.rs41
-rw-r--r--tests/run-make/optimization-remarks-dir/Makefile12
-rw-r--r--tests/run-make/optimization-remarks-dir/rmake.rs39
-rw-r--r--tests/run-make/output-type-permutations/Makefile147
-rw-r--r--tests/run-make/output-type-permutations/rmake.rs543
-rw-r--r--tests/run-make/pgo-gen/Makefile11
-rw-r--r--tests/run-make/pgo-gen/rmake.rs18
-rw-r--r--tests/run-make/pgo-use/Makefile43
-rw-r--r--tests/run-make/pgo-use/rmake.rs55
-rw-r--r--tests/run-make/profile/Makefile13
-rw-r--r--tests/run-make/profile/rmake.rs22
-rw-r--r--tests/run-make/rmeta-preferred/Makefile16
-rw-r--r--tests/run-make/rmeta-preferred/rmake.rs18
-rw-r--r--tests/ui-fulldeps/deriving-global.rs3
-rw-r--r--tests/ui-fulldeps/deriving-hygiene.rs1
-rw-r--r--tests/ui/argument-suggestions/basic.stderr10
-rw-r--r--tests/ui/argument-suggestions/exotic-calls.stderr40
-rw-r--r--tests/ui/argument-suggestions/extra_arguments.stderr169
-rw-r--r--tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr60
-rw-r--r--tests/ui/associated-types/defaults-specialization.stderr18
-rw-r--r--tests/ui/async-await/in-trait/async-generics-and-bounds.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-generics.stderr12
-rw-r--r--tests/ui/compare-method/bad-self-type.stderr20
-rw-r--r--tests/ui/compare-method/issue-90444.stderr18
-rw-r--r--tests/ui/compare-method/reordered-type-param.stderr10
-rw-r--r--tests/ui/const-generics/issues/issue-86535-2.rs1
-rw-r--r--tests/ui/const-generics/issues/issue-86535.rs1
-rw-r--r--tests/ui/consts/offset_from_ub.rs8
-rw-r--r--tests/ui/consts/offset_from_ub.stderr16
-rw-r--r--tests/ui/error-codes/E0057.stderr10
-rw-r--r--tests/ui/error-codes/E0308.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-negate-unsigned.stderr9
-rw-r--r--tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr22
-rw-r--r--tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr4
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.fixed2
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.rs2
-rw-r--r--tests/ui/impl-trait/extra-impl-in-trait-impl.stderr8
-rw-r--r--tests/ui/impl-trait/impl-generic-mismatch-ab.stderr10
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr10
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-broken.stderr9
-rw-r--r--tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr20
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr18
-rw-r--r--tests/ui/impl-trait/trait_type.stderr11
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr9
-rw-r--r--tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr10
-rw-r--r--tests/ui/issues/issue-16939.stderr10
-rw-r--r--tests/ui/issues/issue-20225.stderr27
-rw-r--r--tests/ui/issues/issue-21332.stderr9
-rw-r--r--tests/ui/issues/issue-4935.stderr10
-rw-r--r--tests/ui/lang-items/start_lang_item_args.missing_ret.stderr2
-rw-r--r--tests/ui/lint/dead-code/issue-59003.rs2
-rw-r--r--tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs37
-rw-r--r--tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr20
-rw-r--r--tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs32
-rw-r--r--tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs36
-rw-r--r--tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr24
-rw-r--r--tests/ui/lint/dead-code/unused-struct-derive-default.rs1
-rw-r--r--tests/ui/lint/dead-code/unused-struct-derive-default.stderr1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs1
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr20
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs36
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs37
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr (renamed from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr)20
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs35
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr169
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr (renamed from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr)75
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs40
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr180
-rw-r--r--tests/ui/method-output-diff-issue-127263.rs8
-rw-r--r--tests/ui/method-output-diff-issue-127263.stderr25
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr10
-rw-r--r--tests/ui/mismatched_types/E0053.stderr18
-rw-r--r--tests/ui/mismatched_types/issue-112036.stderr9
-rw-r--r--tests/ui/mismatched_types/issue-13033.stderr9
-rw-r--r--tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr18
-rw-r--r--tests/ui/panic-handler/panic-handler-bad-signature-1.stderr2
-rw-r--r--tests/ui/parser/issues/issue-105366.fixed1
-rw-r--r--tests/ui/parser/issues/issue-105366.rs1
-rw-r--r--tests/ui/parser/issues/issue-105366.stderr2
-rw-r--r--tests/ui/range/issue-54505-no-std.stderr6
-rw-r--r--tests/ui/resolve/resolve-primitive-fallback.stderr10
-rw-r--r--tests/ui/span/issue-34264.stderr20
-rw-r--r--tests/ui/traits/impl-method-mismatch.stderr2
-rw-r--r--tests/ui/traits/issue-35869.stderr36
-rw-r--r--tests/ui/traits/wrong-mul-method-signature.stderr27
-rw-r--r--tests/ui/tuple/wrong_argument_ice-4.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr9
-rw-r--r--tests/ui/type/type-ascription-instead-of-initializer.stderr10
-rw-r--r--tests/ui/typeck/mismatched-map-under-self.stderr9
-rw-r--r--tests/ui/typeck/ptr-null-mutability-suggestions.stderr10
-rw-r--r--tests/ui/typeck/remove-extra-argument.stderr10
-rw-r--r--tests/ui/typeck/struct-enum-wrong-args.stderr30
-rw-r--r--tests/ui/ufcs/ufcs-explicit-self-bad.stderr9
-rw-r--r--tests/ui/unsigned-literal-negation.stderr27
-rw-r--r--triagebot.toml1
226 files changed, 4928 insertions, 2927 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 96cef907084..afeb9faec09 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4168,8 +4168,10 @@ dependencies = [
  "rustc_index",
  "rustc_macros",
  "rustc_middle",
+ "rustc_next_trait_solver",
  "rustc_span",
  "rustc_target",
+ "rustc_type_ir",
  "smallvec",
  "tracing",
 ]
@@ -6356,9 +6358,9 @@ dependencies = [
 
 [[package]]
 name = "windows-bindgen"
-version = "0.57.0"
+version = "0.58.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ccb96113d6277ba543c0f77e1c5494af8094bf9daf9b85acdc3f1b620e7c7b4"
+checksum = "91cd28d93c692351f3a6e5615567c56756e330bee1c99c6bdd57bfc5ab15f589"
 dependencies = [
  "proc-macro2",
  "rayon",
@@ -6379,9 +6381,9 @@ dependencies = [
 
 [[package]]
 name = "windows-metadata"
-version = "0.57.0"
+version = "0.58.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8308d076825b9d9e5abc64f8113e96d02b2aeeba869b20fdd65c7e70cda13dfc"
+checksum = "2e837f3c3012cfe9e7086302a93f441a7999439be1ad4c530d55d2f6d2921809"
 
 [[package]]
 name = "windows-sys"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index dbbc4980050..75c656973f9 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -176,7 +176,7 @@ pub enum GenericArgs {
     AngleBracketed(AngleBracketedArgs),
     /// The `(A, B)` and `C` in `Foo(A, B) -> C`.
     Parenthesized(ParenthesizedArgs),
-    /// `(..)` in return type notation
+    /// `(..)` in return type notation.
     ParenthesizedElided(Span),
 }
 
@@ -197,11 +197,11 @@ impl GenericArgs {
 /// Concrete argument in the sequence of generic args.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum GenericArg {
-    /// `'a` in `Foo<'a>`
+    /// `'a` in `Foo<'a>`.
     Lifetime(Lifetime),
-    /// `Bar` in `Foo<Bar>`
+    /// `Bar` in `Foo<Bar>`.
     Type(P<Ty>),
-    /// `1` in `Foo<1>`
+    /// `1` in `Foo<1>`.
     Const(AnonConst),
 }
 
@@ -355,7 +355,7 @@ pub enum GenericParamKind {
         ty: P<Ty>,
         /// Span of the `const` keyword.
         kw_span: Span,
-        /// Optional default value for the const generic param
+        /// Optional default value for the const generic param.
         default: Option<AnonConst>,
     },
 }
@@ -714,6 +714,7 @@ pub enum ByRef {
 }
 
 impl ByRef {
+    #[must_use]
     pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
         if let ByRef::Yes(old_mutbl) = &mut self {
             *old_mutbl = cmp::min(*old_mutbl, mutbl);
@@ -832,7 +833,7 @@ pub enum PatKind {
     /// only one rest pattern may occur in the pattern sequences.
     Rest,
 
-    // A never pattern `!`
+    // A never pattern `!`.
     Never,
 
     /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
@@ -1121,9 +1122,9 @@ impl LocalKind {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct Arm {
     pub attrs: AttrVec,
-    /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`
+    /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
     pub pat: P<Pat>,
-    /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`
+    /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`.
     pub guard: Option<P<Expr>>,
     /// Match arm body. Omitted if the pattern is a never pattern.
     pub body: Option<P<Expr>>,
@@ -1354,12 +1355,12 @@ pub struct Closure {
     pub fn_arg_span: Span,
 }
 
-/// Limit types of a range (inclusive or exclusive)
+/// Limit types of a range (inclusive or exclusive).
 #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)]
 pub enum RangeLimits {
-    /// Inclusive at the beginning, exclusive at the end
+    /// Inclusive at the beginning, exclusive at the end.
     HalfOpen,
-    /// Inclusive at the beginning and end
+    /// Inclusive at the beginning and end.
     Closed,
 }
 
@@ -1400,9 +1401,9 @@ pub struct StructExpr {
 pub enum ExprKind {
     /// An array (e.g, `[a, b, c, d]`).
     Array(ThinVec<P<Expr>>),
-    /// Allow anonymous constants from an inline `const` block
+    /// Allow anonymous constants from an inline `const` block.
     ConstBlock(AnonConst),
-    /// A function call
+    /// A function call.
     ///
     /// The first field resolves to the function itself,
     /// and the second field is the list of arguments.
@@ -1456,7 +1457,7 @@ pub enum ExprKind {
     /// A block (`'label: { ... }`).
     Block(P<Block>, Option<Label>),
     /// An `async` block (`async move { ... }`),
-    /// or a `gen` block (`gen move { ... }`)
+    /// or a `gen` block (`gen move { ... }`).
     ///
     /// The span is the "decl", which is the header before the body `{ }`
     /// including the `asyng`/`gen` keywords and possibly `move`.
@@ -2156,9 +2157,9 @@ pub enum TyKind {
     Never,
     /// A tuple (`(A, B, C, D,...)`).
     Tup(ThinVec<P<Ty>>),
-    /// An anonymous struct type i.e. `struct { foo: Type }`
+    /// An anonymous struct type i.e. `struct { foo: Type }`.
     AnonStruct(NodeId, ThinVec<FieldDef>),
-    /// An anonymous union type i.e. `union { bar: Type }`
+    /// An anonymous union type i.e. `union { bar: Type }`.
     AnonUnion(NodeId, ThinVec<FieldDef>),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
@@ -2232,9 +2233,9 @@ pub enum TraitObjectSyntax {
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum PreciseCapturingArg {
-    /// Lifetime parameter
+    /// Lifetime parameter.
     Lifetime(Lifetime),
-    /// Type or const parameter
+    /// Type or const parameter.
     Arg(Path, NodeId),
 }
 
@@ -2528,11 +2529,11 @@ pub enum Safety {
 /// Iterator`.
 #[derive(Copy, Clone, Encodable, Decodable, Debug)]
 pub enum CoroutineKind {
-    /// `async`, which returns an `impl Future`
+    /// `async`, which returns an `impl Future`.
     Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
-    /// `gen`, which returns an `impl Iterator`
+    /// `gen`, which returns an `impl Iterator`.
     Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
-    /// `async gen`, which returns an `impl AsyncIterator`
+    /// `async gen`, which returns an `impl AsyncIterator`.
     AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
 }
 
@@ -2749,7 +2750,7 @@ pub struct Variant {
     pub data: VariantData,
     /// Explicit discriminant, e.g., `Foo = 1`.
     pub disr_expr: Option<AnonConst>,
-    /// Is a macro placeholder
+    /// Is a macro placeholder.
     pub is_placeholder: bool,
 }
 
@@ -3023,19 +3024,19 @@ impl Item {
 /// `extern` qualifier on a function item or function type.
 #[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub enum Extern {
-    /// No explicit extern keyword was used
+    /// No explicit extern keyword was used.
     ///
-    /// E.g. `fn foo() {}`
+    /// E.g. `fn foo() {}`.
     None,
-    /// An explicit extern keyword was used, but with implicit ABI
+    /// An explicit extern keyword was used, but with implicit ABI.
     ///
-    /// E.g. `extern fn foo() {}`
+    /// E.g. `extern fn foo() {}`.
     ///
-    /// This is just `extern "C"` (see `rustc_target::spec::abi::Abi::FALLBACK`)
+    /// This is just `extern "C"` (see `rustc_target::spec::abi::Abi::FALLBACK`).
     Implicit(Span),
-    /// An explicit extern keyword was used with an explicit ABI
+    /// An explicit extern keyword was used with an explicit ABI.
     ///
-    /// E.g. `extern "C" fn foo() {}`
+    /// E.g. `extern "C" fn foo() {}`.
     Explicit(StrLit, Span),
 }
 
@@ -3054,13 +3055,13 @@ impl Extern {
 /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
 #[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub struct FnHeader {
-    /// Whether this is `unsafe`, or has a default safety
+    /// Whether this is `unsafe`, or has a default safety.
     pub safety: Safety,
     /// Whether this is `async`, `gen`, or nothing.
     pub coroutine_kind: Option<CoroutineKind>,
     /// The `const` keyword, if any
     pub constness: Const,
-    /// The `extern` keyword and corresponding ABI string, if any
+    /// The `extern` keyword and corresponding ABI string, if any.
     pub ext: Extern,
 }
 
@@ -3254,7 +3255,7 @@ pub enum ItemKind {
     ///
     /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
     Trait(Box<Trait>),
-    /// Trait alias
+    /// Trait alias.
     ///
     /// E.g., `trait Foo = Bar + Quux;`.
     TraitAlias(Generics, GenericBounds),
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index e291ebd9bb8..c2c3f5bc79e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -39,6 +39,7 @@ use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
 use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
 use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
 use std::iter;
+use std::ops::ControlFlow;
 
 use crate::borrow_set::TwoPhaseActivation;
 use crate::borrowck_errors;
@@ -784,20 +785,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         /// binding declaration within every scope we inspect.
         struct Finder {
             hir_id: hir::HirId,
-            found: bool,
         }
         impl<'hir> Visitor<'hir> for Finder {
-            fn visit_pat(&mut self, pat: &'hir hir::Pat<'hir>) {
+            type Result = ControlFlow<()>;
+            fn visit_pat(&mut self, pat: &'hir hir::Pat<'hir>) -> Self::Result {
                 if pat.hir_id == self.hir_id {
-                    self.found = true;
+                    return ControlFlow::Break(());
                 }
-                hir::intravisit::walk_pat(self, pat);
+                hir::intravisit::walk_pat(self, pat)
             }
-            fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
+            fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) -> Self::Result {
                 if ex.hir_id == self.hir_id {
-                    self.found = true;
+                    return ControlFlow::Break(());
                 }
-                hir::intravisit::walk_expr(self, ex);
+                hir::intravisit::walk_expr(self, ex)
             }
         }
         // The immediate HIR parent of the moved expression. We'll look for it to be a call.
@@ -822,9 +823,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                 _ => continue,
             };
             if let Some(&hir_id) = local_hir_id {
-                let mut finder = Finder { hir_id, found: false };
-                finder.visit_expr(e);
-                if finder.found {
+                if (Finder { hir_id }).visit_expr(e).is_break() {
                     // The current scope includes the declaration of the binding we're accessing, we
                     // can't look up any further for loops.
                     break;
@@ -839,9 +838,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                         hir::Node::Expr(hir::Expr {
                             kind: hir::ExprKind::If(cond, ..), ..
                         }) => {
-                            let mut finder = Finder { hir_id: expr.hir_id, found: false };
-                            finder.visit_expr(cond);
-                            if finder.found {
+                            if (Finder { hir_id: expr.hir_id }).visit_expr(cond).is_break() {
                                 // The expression where the move error happened is in a `while let`
                                 // condition Don't suggest clone as it will likely end in an
                                 // infinite loop.
@@ -1837,7 +1834,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
 
         pub struct Holds<'tcx> {
             ty: Ty<'tcx>,
-            holds: bool,
         }
 
         impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Holds<'tcx> {
@@ -1845,7 +1841,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
 
             fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
                 if t == self.ty {
-                    self.holds = true;
+                    return ControlFlow::Break(());
                 }
                 t.super_visit_with(self)
             }
@@ -1863,9 +1859,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
                 && rcvr_ty == ty
                 && let ty::Ref(_, inner, _) = rcvr_ty.kind()
                 && let inner = inner.peel_refs()
-                && let mut v = (Holds { ty: inner, holds: false })
-                && let _ = v.visit_ty(local_ty)
-                && v.holds
+                && (Holds { ty: inner }).visit_ty(local_ty).is_break()
                 && let None = self.infcx.type_implements_trait_shallow(clone, inner, self.param_env)
             {
                 err.span_label(
@@ -4325,15 +4319,14 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
 }
 
 /// Detect whether one of the provided spans is a statement nested within the top-most visited expr
-struct ReferencedStatementsVisitor<'a>(&'a [Span], bool);
+struct ReferencedStatementsVisitor<'a>(&'a [Span]);
 
-impl<'a, 'v> Visitor<'v> for ReferencedStatementsVisitor<'a> {
-    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
+impl<'v> Visitor<'v> for ReferencedStatementsVisitor<'_> {
+    type Result = ControlFlow<()>;
+    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) -> Self::Result {
         match s.kind {
-            hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => {
-                self.1 = true;
-            }
-            _ => {}
+            hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => ControlFlow::Break(()),
+            _ => ControlFlow::Continue(()),
         }
     }
 }
@@ -4375,9 +4368,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
             hir::ExprKind::If(cond, body, None) => {
                 // `if` expressions with no `else` that initialize the binding might be missing an
                 // `else` arm.
-                let mut v = ReferencedStatementsVisitor(self.spans, false);
-                v.visit_expr(body);
-                if v.1 {
+                if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() {
                     self.errors.push((
                         cond.span,
                         format!(
@@ -4394,11 +4385,9 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
             hir::ExprKind::If(cond, body, Some(other)) => {
                 // `if` expressions where the binding is only initialized in one of the two arms
                 // might be missing a binding initialization.
-                let mut a = ReferencedStatementsVisitor(self.spans, false);
-                a.visit_expr(body);
-                let mut b = ReferencedStatementsVisitor(self.spans, false);
-                b.visit_expr(other);
-                match (a.1, b.1) {
+                let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break();
+                let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break();
+                match (a, b) {
                     (true, true) | (false, false) => {}
                     (true, false) => {
                         if other.span.is_desugaring(DesugaringKind::WhileLoop) {
@@ -4437,11 +4426,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
                 // arms might be missing an initialization.
                 let results: Vec<bool> = arms
                     .iter()
-                    .map(|arm| {
-                        let mut v = ReferencedStatementsVisitor(self.spans, false);
-                        v.visit_arm(arm);
-                        v.1
-                    })
+                    .map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break())
                     .collect();
                 if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
                     for (arm, seen) in arms.iter().zip(results) {
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index b9a82046e59..02b9c2d48b1 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,8 +1,9 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
-use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
-use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation};
-use rustc_infer::infer::NllRegionVariableOrigin;
+use rustc_infer::infer::relate::{
+    PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation,
+};
+use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
 use rustc_infer::traits::solve::Goal;
 use rustc_infer::traits::Obligation;
 use rustc_middle::mir::ConstraintCategory;
@@ -522,7 +523,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
     }
 }
 
-impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
+impl<'bccx, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx> {
     fn span(&self) -> Span {
         self.locations.span(self.type_checker.body)
     }
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 577523a1d5a..7a65ed97f00 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -240,7 +240,7 @@ fn has_a_default_variant(item: &Annotatable) -> bool {
             if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
                 ControlFlow::Break(())
             } else {
-                // no need to subrecurse.
+                // no need to walk the variant, we are only looking for top level variants
                 ControlFlow::Continue(())
             }
         }
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 1d54da267ee..d86f1a7a34f 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -301,9 +301,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                         }
                         // The signed form of the intrinsic allows this. If we interpret the
                         // difference as isize, we'll get the proper signed difference. If that
-                        // seems *positive*, they were more than isize::MAX apart.
+                        // seems *positive* or equal to isize::MIN, they were more than isize::MAX apart.
                         let dist = val.to_target_isize(self)?;
-                        if dist >= 0 {
+                        if dist >= 0 || i128::from(dist) == self.pointer_size().signed_int_min() {
                             throw_ub_custom!(
                                 fluent::const_eval_offset_from_underflow,
                                 name = intrinsic_name,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0502.md b/compiler/rustc_error_codes/src/error_codes/E0502.md
index dc3ffdfddd9..85f38b9286f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0502.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0502.md
@@ -1,4 +1,5 @@
-A variable already borrowed as immutable was borrowed as mutable.
+A variable already borrowed with a certain mutability (either mutable or
+immutable) was borrowed again with a different mutability.
 
 Erroneous code example:
 
@@ -13,7 +14,7 @@ fn foo(a: &mut i32) {
 ```
 
 To fix this error, ensure that you don't have any other references to the
-variable before trying to access it mutably:
+variable before trying to access it with a different mutability:
 
 ```
 fn bar(x: &mut i32) {}
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index ad6f7da8937..c05cac155b7 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -575,6 +575,8 @@ declare_features! (
     (unstable, raw_ref_op, "1.41.0", Some(64490)),
     /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
     (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
+    /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant
+    (incomplete, ref_pat_eat_one_layer_2024_structural, "CURRENT_RUSTC_VERSION", Some(123076)),
     /// Allows using the `#[register_tool]` attribute.
     (unstable, register_tool, "1.41.0", Some(66079)),
     /// Allows the `#[repr(i128)]` attribute for enums.
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index b5b68471b9d..0dbe64c3ea7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -981,7 +981,7 @@ fn report_trait_method_mismatch<'tcx>(
                 .next()
                 .unwrap_or(impl_err_span);
 
-            diag.span_suggestion(
+            diag.span_suggestion_verbose(
                 span,
                 "change the self-receiver type to match the trait",
                 sugg,
@@ -1005,12 +1005,12 @@ fn report_trait_method_mismatch<'tcx>(
                         }
                         hir::FnRetTy::Return(hir_ty) => {
                             let sugg = trait_sig.output();
-                            diag.span_suggestion(hir_ty.span, msg, sugg, ap);
+                            diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap);
                         }
                     };
                 };
             } else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
-                diag.span_suggestion(
+                diag.span_suggestion_verbose(
                     impl_err_span,
                     "change the parameter type to match the trait",
                     trait_ty,
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 9b02c1a61fa..22d465c8e62 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use crate::middle::resolve_bound_vars as rbv;
 use hir::{
     intravisit::{self, Visitor},
@@ -87,14 +89,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
             let mut in_param_ty = false;
             for (_parent, node) in tcx.hir().parent_iter(hir_id) {
                 if let Some(generics) = node.generics() {
-                    let mut visitor = AnonConstInParamTyDetector {
-                        in_param_ty: false,
-                        found_anon_const_in_param_ty: false,
-                        ct: hir_id,
-                    };
+                    let mut visitor = AnonConstInParamTyDetector { in_param_ty: false, ct: hir_id };
 
-                    visitor.visit_generics(generics);
-                    in_param_ty = visitor.found_anon_const_in_param_ty;
+                    in_param_ty = visitor.visit_generics(generics).is_break();
                     break;
                 }
             }
@@ -460,50 +457,45 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
     struct LateBoundRegionsDetector<'tcx> {
         tcx: TyCtxt<'tcx>,
         outer_index: ty::DebruijnIndex,
-        has_late_bound_regions: Option<Span>,
     }
 
     impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> {
-        fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
+        type Result = ControlFlow<Span>;
+        fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) -> ControlFlow<Span> {
             match ty.kind {
                 hir::TyKind::BareFn(..) => {
                     self.outer_index.shift_in(1);
-                    intravisit::walk_ty(self, ty);
+                    let res = intravisit::walk_ty(self, ty);
                     self.outer_index.shift_out(1);
+                    res
                 }
                 _ => intravisit::walk_ty(self, ty),
             }
         }
 
-        fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
+        fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) -> ControlFlow<Span> {
             self.outer_index.shift_in(1);
-            intravisit::walk_poly_trait_ref(self, tr);
+            let res = intravisit::walk_poly_trait_ref(self, tr);
             self.outer_index.shift_out(1);
+            res
         }
 
-        fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
-            if self.has_late_bound_regions.is_some() {
-                return;
-            }
-
+        fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) -> ControlFlow<Span> {
             match self.tcx.named_bound_var(lt.hir_id) {
-                Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {}
+                Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {
+                    ControlFlow::Continue(())
+                }
                 Some(rbv::ResolvedArg::LateBound(debruijn, _, _))
-                    if debruijn < self.outer_index => {}
+                    if debruijn < self.outer_index =>
+                {
+                    ControlFlow::Continue(())
+                }
                 Some(
                     rbv::ResolvedArg::LateBound(..)
                     | rbv::ResolvedArg::Free(..)
                     | rbv::ResolvedArg::Error(_),
                 )
-                | None => {
-                    self.has_late_bound_regions = Some(lt.ident.span);
-                }
+                | None => ControlFlow::Break(lt.ident.span),
             }
         }
     }
@@ -513,11 +505,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
         generics: &'tcx hir::Generics<'tcx>,
         decl: &'tcx hir::FnDecl<'tcx>,
     ) -> Option<Span> {
-        let mut visitor = LateBoundRegionsDetector {
-            tcx,
-            outer_index: ty::INNERMOST,
-            has_late_bound_regions: None,
-        };
+        let mut visitor = LateBoundRegionsDetector { tcx, outer_index: ty::INNERMOST };
         for param in generics.params {
             if let GenericParamKind::Lifetime { .. } = param.kind {
                 if tcx.is_late_bound(param.hir_id) {
@@ -525,8 +513,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
                 }
             }
         }
-        visitor.visit_fn_decl(decl);
-        visitor.has_late_bound_regions
+        visitor.visit_fn_decl(decl).break_value()
     }
 
     let decl = node.fn_decl()?;
@@ -536,26 +523,29 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
 
 struct AnonConstInParamTyDetector {
     in_param_ty: bool,
-    found_anon_const_in_param_ty: bool,
     ct: HirId,
 }
 
 impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
-    fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
+    type Result = ControlFlow<()>;
+
+    fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) -> Self::Result {
         if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind
         {
             let prev = self.in_param_ty;
             self.in_param_ty = true;
-            self.visit_ty(ty);
+            let res = self.visit_ty(ty);
             self.in_param_ty = prev;
+            res
+        } else {
+            ControlFlow::Continue(())
         }
     }
 
-    fn visit_anon_const(&mut self, c: &'v hir::AnonConst) {
+    fn visit_anon_const(&mut self, c: &'v hir::AnonConst) -> Self::Result {
         if self.in_param_ty && self.ct == c.hir_id {
-            self.found_anon_const_in_param_ty = true;
-        } else {
-            intravisit::walk_anon_const(self, c)
+            return ControlFlow::Break(());
         }
+        intravisit::walk_anon_const(self, c)
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index 5086c2af3f6..08015c28a26 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -1,9 +1,9 @@
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
 use rustc_middle::ty::{self, Region, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
+use rustc_type_ir::outlives::{push_outlives_components, Component};
 use smallvec::smallvec;
 
 /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index e49b921e63c..f1ed2ade3d4 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -501,6 +501,7 @@ pub enum SuggestBoxing {
 #[suggestion(
     hir_typeck_suggest_ptr_null_mut,
     applicability = "maybe-incorrect",
+    style = "verbose",
     code = "core::ptr::null_mut()"
 )]
 pub struct SuggestPtrNullMut {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 56dff080867..047d0850d4c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1384,7 +1384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(format!("provide the argument{}", if plural { "s" } else { "" }))
             }
             SuggestionText::Remove(plural) => {
-                err.multipart_suggestion(
+                err.multipart_suggestion_verbose(
                     format!("remove the extra argument{}", if plural { "s" } else { "" }),
                     suggestions,
                     Applicability::HasPlaceholders,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
index fab7eb7495c..90dd5f73586 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs
@@ -104,8 +104,6 @@ struct NestedObligationsForSelfTy<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
-    type Result = ();
-
     fn span(&self) -> Span {
         self.root_cause.span
     }
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 5a11cb7096f..7264bc5a78d 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -838,8 +838,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     },
                                 ) = ex.kind
                                 {
-                                    err.span_suggestion(
-                                        ex.span,
+                                    let span = if let hir::Node::Expr(parent) =
+                                        self.tcx.parent_hir_node(ex.hir_id)
+                                        && let hir::ExprKind::Cast(..) = parent.kind
+                                    {
+                                        // `-1 as usize` -> `usize::MAX`
+                                        parent.span
+                                    } else {
+                                        ex.span
+                                    };
+                                    err.span_suggestion_verbose(
+                                        span,
                                         format!(
                                             "you may have meant the maximum value of `{actual}`",
                                         ),
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 478bbc0ed98..5e0f37ed792 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -328,8 +328,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         adjust_mode: AdjustMode,
         max_ref_mutbl: MutblCap,
     ) -> (Ty<'tcx>, ByRef, MutblCap) {
-        if let ByRef::Yes(Mutability::Mut) = def_br {
-            debug_assert!(max_ref_mutbl == MutblCap::Mut);
+        #[cfg(debug_assertions)]
+        if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut {
+            span_bug!(pat.span, "Pattern mutability cap violated!");
         }
         match adjust_mode {
             AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
@@ -437,7 +438,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
         }
 
-        if self.tcx.features().ref_pat_eat_one_layer_2024 {
+        let features = self.tcx.features();
+        if features.ref_pat_eat_one_layer_2024 || features.ref_pat_eat_one_layer_2024_structural {
             def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
             if def_br == ByRef::Yes(Mutability::Not) {
                 max_ref_mutbl = MutblCap::Not;
@@ -669,7 +671,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Determine the binding mode...
         let bm = match user_bind_annot {
             BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
-                if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
+                if pat.span.at_least_rust_2024()
+                    && (self.tcx.features().ref_pat_eat_one_layer_2024
+                        || self.tcx.features().ref_pat_eat_one_layer_2024_structural)
+                {
                     if !self.tcx.features().mut_ref {
                         feature_err(
                             &self.tcx.sess,
@@ -2123,7 +2128,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mut expected: Ty<'tcx>,
         mut pat_info: PatInfo<'tcx, '_>,
     ) -> Ty<'tcx> {
-        let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
+        let tcx = self.tcx;
+        let features = tcx.features();
+        let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024;
+        let ref_pat_eat_one_layer_2024_structural = features.ref_pat_eat_one_layer_2024_structural;
+
+        let no_ref_mut_behind_and =
+            ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural;
         let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
 
         let pat_prefix_span =
@@ -2138,32 +2149,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             pat_info.max_ref_mutbl = MutblCap::Mut;
         }
 
+        expected = self.try_structurally_resolve_type(pat.span, expected);
         if new_match_ergonomics {
             if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
-                // ref pattern consumes inherited reference
-
-                if pat_mutbl > inh_mut {
-                    // Tried to match inherited `ref` with `&mut`, which is an error
-                    let err_msg = "cannot match inherited `&` with `&mut` pattern";
-                    let err = if let Some(span) = pat_prefix_span {
-                        let mut err = self.dcx().struct_span_err(span, err_msg);
-                        err.span_suggestion_verbose(
-                            span,
-                            "replace this `&mut` pattern with `&`",
-                            "&",
-                            Applicability::MachineApplicable,
-                        );
-                        err
+                if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() {
+                    // Don't attempt to consume inherited reference
+                    pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl);
+                } else {
+                    // ref pattern attempts to consume inherited reference
+                    if pat_mutbl > inh_mut {
+                        // Tried to match inherited `ref` with `&mut`
+                        if !ref_pat_eat_one_layer_2024_structural {
+                            let err_msg = "mismatched types";
+                            let err = if let Some(span) = pat_prefix_span {
+                                let mut err = self.dcx().struct_span_err(span, err_msg);
+                                err.code(E0308);
+                                err.note("cannot match inherited `&` with `&mut` pattern");
+                                err.span_suggestion_verbose(
+                                    span,
+                                    "replace this `&mut` pattern with `&`",
+                                    "&",
+                                    Applicability::MachineApplicable,
+                                );
+                                err
+                            } else {
+                                self.dcx().struct_span_err(pat.span, err_msg)
+                            };
+                            err.emit();
+
+                            pat_info.binding_mode = ByRef::No;
+                            self.typeck_results
+                                .borrow_mut()
+                                .skipped_ref_pats_mut()
+                                .insert(pat.hir_id);
+                            self.check_pat(inner, expected, pat_info);
+                            return expected;
+                        }
                     } else {
-                        self.dcx().struct_span_err(pat.span, err_msg)
-                    };
-                    err.emit();
+                        pat_info.binding_mode = ByRef::No;
+                        self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
+                        self.check_pat(inner, expected, pat_info);
+                        return expected;
+                    }
                 }
-
-                pat_info.binding_mode = ByRef::No;
-                self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
-                self.check_pat(inner, expected, pat_info);
-                return expected;
             }
         } else {
             // Reset binding mode on old editions
@@ -2178,8 +2206,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        let tcx = self.tcx;
-        expected = self.try_structurally_resolve_type(pat.span, expected);
         let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
             Ok(()) => {
                 // `demand::subtype` would be good enough, but using `eqtype` turns
@@ -2191,7 +2217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 debug!("check_pat_ref: expected={:?}", expected);
                 match *expected.kind() {
                     ty::Ref(_, r_ty, r_mutbl)
-                        if (new_match_ergonomics && r_mutbl >= pat_mutbl)
+                        if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl)
                             || r_mutbl == pat_mutbl =>
                     {
                         if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index b6e9000ef95..c99e8a7fe8e 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -18,7 +18,7 @@ use rustc_trait_selection::traits::{
 use std::cell::RefCell;
 use std::ops::Deref;
 
-// Data shared between a "typeck root" and its nested bodies,
+/// Data shared between a "typeck root" and its nested bodies,
 /// e.g. closures defined within the function. For example:
 /// ```ignore (illustrative)
 /// fn foo() {
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
index c1565a7d40f..1f616710200 100644
--- a/compiler/rustc_infer/Cargo.toml
+++ b/compiler/rustc_infer/Cargo.toml
@@ -16,8 +16,10 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
+rustc_next_trait_solver = { path = "../rustc_next_trait_solver" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
+rustc_type_ir = { path = "../rustc_type_ir" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs
new file mode 100644
index 00000000000..209996b12e2
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/context.rs
@@ -0,0 +1,172 @@
+///! Definition of `InferCtxtLike` from the librarified type layer.
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_middle::traits::solve::{Goal, NoSolution, SolverMode};
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::DUMMY_SP;
+use rustc_type_ir::relate::Relate;
+use rustc_type_ir::InferCtxtLike;
+
+use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
+
+impl<'tcx> InferCtxtLike for InferCtxt<'tcx> {
+    type Interner = TyCtxt<'tcx>;
+
+    fn cx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn solver_mode(&self) -> ty::solve::SolverMode {
+        match self.intercrate {
+            true => SolverMode::Coherence,
+            false => SolverMode::Normal,
+        }
+    }
+
+    fn universe(&self) -> ty::UniverseIndex {
+        self.universe()
+    }
+
+    fn create_next_universe(&self) -> ty::UniverseIndex {
+        self.create_next_universe()
+    }
+
+    fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
+        match self.probe_ty_var(vid) {
+            Err(universe) => Some(universe),
+            Ok(_) => None,
+        }
+    }
+
+    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
+        match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
+            Err(universe) => Some(universe),
+            Ok(_) => None,
+        }
+    }
+
+    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> {
+        match self.probe_const_var(ct) {
+            Err(universe) => Some(universe),
+            Ok(_) => None,
+        }
+    }
+
+    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
+        self.root_var(var)
+    }
+
+    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
+        self.root_const_var(var)
+    }
+
+    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> {
+        match self.probe_ty_var(vid) {
+            Ok(ty) => ty,
+            Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
+        }
+    }
+
+    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
+        self.opportunistic_resolve_int_var(vid)
+    }
+
+    fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
+        self.opportunistic_resolve_float_var(vid)
+    }
+
+    fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> {
+        match self.probe_const_var(vid) {
+            Ok(ct) => ct,
+            Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
+        }
+    }
+
+    fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> {
+        match self.probe_effect_var(vid) {
+            Some(ct) => ct,
+            None => {
+                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(self.root_effect_var(vid)))
+            }
+        }
+    }
+
+    fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
+        self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
+    }
+
+    fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
+        self.defining_opaque_types()
+    }
+
+    fn next_ty_infer(&self) -> Ty<'tcx> {
+        self.next_ty_var(DUMMY_SP)
+    }
+
+    fn next_const_infer(&self) -> ty::Const<'tcx> {
+        self.next_const_var(DUMMY_SP)
+    }
+
+    fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
+        self.fresh_args_for_item(DUMMY_SP, def_id)
+    }
+
+    fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
+        &self,
+        value: ty::Binder<'tcx, T>,
+    ) -> T {
+        self.instantiate_binder_with_fresh_vars(
+            DUMMY_SP,
+            BoundRegionConversionTime::HigherRankedType,
+            value,
+        )
+    }
+
+    fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
+        &self,
+        value: ty::Binder<'tcx, T>,
+        f: impl FnOnce(T) -> U,
+    ) -> U {
+        self.enter_forall(value, f)
+    }
+
+    fn relate<T: Relate<TyCtxt<'tcx>>>(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        variance: ty::Variance,
+        rhs: T,
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
+        self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
+    }
+
+    fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        rhs: T,
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
+        self.at(&ObligationCause::dummy(), param_env)
+            .eq_structurally_relating_aliases_no_trace(lhs, rhs)
+    }
+
+    fn resolve_vars_if_possible<T>(&self, value: T) -> T
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        self.resolve_vars_if_possible(value)
+    }
+
+    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
+        self.probe(|_| probe())
+    }
+
+    fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
+        self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
+    }
+
+    fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
+        self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy());
+    }
+}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index a8fd3ca8c59..cebb9d09a47 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1168,14 +1168,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let output1 = sig1.output();
         let output2 = sig2.output();
         let (x1, x2) = self.cmp(output1, output2);
-        if !output1.is_unit() {
+        let output_diff = x1 != x2;
+        if !output1.is_unit() || output_diff {
             values.0.push_normal(" -> ");
             (values.0).0.extend(x1.0);
         }
-        if !output2.is_unit() {
+        if !output2.is_unit() || output_diff {
             values.1.push_normal(" -> ");
             (values.1).0.extend(x2.0);
         }
+
         values
     }
 
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index ff593d7ffb7..edbb741036f 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -53,6 +53,7 @@ use type_variable::TypeVariableOrigin;
 
 pub mod at;
 pub mod canonical;
+mod context;
 pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
deleted file mode 100644
index 6bab3ad6ba3..00000000000
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ /dev/null
@@ -1,266 +0,0 @@
-// The outlines relation `T: 'a` or `'a: 'b`. This code frequently
-// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
-// RFC for reference.
-
-use rustc_data_structures::sso::SsoHashSet;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
-use rustc_middle::ty::{GenericArg, GenericArgKind};
-use smallvec::{smallvec, SmallVec};
-
-#[derive(Debug)]
-pub enum Component<'tcx> {
-    Region(ty::Region<'tcx>),
-    Param(ty::ParamTy),
-    Placeholder(ty::PlaceholderType),
-    UnresolvedInferenceVariable(ty::InferTy),
-
-    // Projections like `T::Foo` are tricky because a constraint like
-    // `T::Foo: 'a` can be satisfied in so many ways. There may be a
-    // where-clause that says `T::Foo: 'a`, or the defining trait may
-    // include a bound like `type Foo: 'static`, or -- in the most
-    // conservative way -- we can prove that `T: 'a` (more generally,
-    // that all components in the projection outlive `'a`). This code
-    // is not in a position to judge which is the best technique, so
-    // we just product the projection as a component and leave it to
-    // the consumer to decide (but see `EscapingProjection` below).
-    Alias(ty::AliasTy<'tcx>),
-
-    // In the case where a projection has escaping regions -- meaning
-    // regions bound within the type itself -- we always use
-    // the most conservative rule, which requires that all components
-    // outlive the bound. So for example if we had a type like this:
-    //
-    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >
-    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~
-    //
-    // then the inner projection (underlined) has an escaping region
-    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`
-    // outlives `'b: 'c`, and we don't consider whether the trait
-    // declares that `Foo: 'static` etc. Therefore, we just return the
-    // free components of such a projection (in this case, `'b`).
-    //
-    // However, in the future, we may want to get smarter, and
-    // actually return a "higher-ranked projection" here. Therefore,
-    // we mark that these components are part of an escaping
-    // projection, so that implied bounds code can avoid relying on
-    // them. This gives us room to improve the regionck reasoning in
-    // the future without breaking backwards compat.
-    EscapingAlias(Vec<Component<'tcx>>),
-}
-
-/// Push onto `out` all the things that must outlive `'a` for the condition
-/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
-pub fn push_outlives_components<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    ty0: Ty<'tcx>,
-    out: &mut SmallVec<[Component<'tcx>; 4]>,
-) {
-    let mut visited = SsoHashSet::new();
-    compute_components(tcx, ty0, out, &mut visited);
-    debug!("components({:?}) = {:?}", ty0, out);
-}
-
-fn compute_components<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    ty: Ty<'tcx>,
-    out: &mut SmallVec<[Component<'tcx>; 4]>,
-    visited: &mut SsoHashSet<GenericArg<'tcx>>,
-) {
-    // Descend through the types, looking for the various "base"
-    // components and collecting them into `out`. This is not written
-    // with `collect()` because of the need to sometimes skip subtrees
-    // in the `subtys` iterator (e.g., when encountering a
-    // projection).
-    match *ty.kind() {
-            ty::FnDef(_, args) => {
-                // HACK(eddyb) ignore lifetimes found shallowly in `args`.
-                // This is inconsistent with `ty::Adt` (including all args)
-                // and with `ty::Closure` (ignoring all args other than
-                // upvars, of which a `ty::FnDef` doesn't have any), but
-                // consistent with previous (accidental) behavior.
-                // See https://github.com/rust-lang/rust/issues/70917
-                // for further background and discussion.
-                for child in args {
-                    match child.unpack() {
-                        GenericArgKind::Type(ty) => {
-                            compute_components(tcx, ty, out, visited);
-                        }
-                        GenericArgKind::Lifetime(_) => {}
-                        GenericArgKind::Const(_) => {
-                            compute_components_recursive(tcx, child, out, visited);
-                        }
-                    }
-                }
-            }
-
-            ty::Pat(element, _) |
-            ty::Array(element, _) => {
-                // Don't look into the len const as it doesn't affect regions
-                compute_components(tcx, element, out, visited);
-            }
-
-            ty::Closure(_, args) => {
-                let tupled_ty = args.as_closure().tupled_upvars_ty();
-                compute_components(tcx, tupled_ty, out, visited);
-            }
-
-            ty::CoroutineClosure(_, args) => {
-                let tupled_ty = args.as_coroutine_closure().tupled_upvars_ty();
-                compute_components(tcx, tupled_ty, out, visited);
-            }
-
-            ty::Coroutine(_, args) => {
-                // Same as the closure case
-                let tupled_ty = args.as_coroutine().tupled_upvars_ty();
-                compute_components(tcx, tupled_ty, out, visited);
-
-                // We ignore regions in the coroutine interior as we don't
-                // want these to affect region inference
-            }
-
-            // All regions are bound inside a witness
-            ty::CoroutineWitness(..) => (),
-
-            // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
-            // is implied by the environment is done in regionck.
-            ty::Param(p) => {
-                out.push(Component::Param(p));
-            }
-
-            ty::Placeholder(p) => {
-                out.push(Component::Placeholder(p));
-            }
-
-            // For projections, we prefer to generate an obligation like
-            // `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
-            // regionck more ways to prove that it holds. However,
-            // regionck is not (at least currently) prepared to deal with
-            // higher-ranked regions that may appear in the
-            // trait-ref. Therefore, if we see any higher-ranked regions,
-            // we simply fallback to the most restrictive rule, which
-            // requires that `Pi: 'a` for all `i`.
-            ty::Alias(_, alias_ty) => {
-                if !alias_ty.has_escaping_bound_vars() {
-                    // best case: no escaping regions, so push the
-                    // projection and skip the subtree (thus generating no
-                    // constraints for Pi). This defers the choice between
-                    // the rules OutlivesProjectionEnv,
-                    // OutlivesProjectionTraitDef, and
-                    // OutlivesProjectionComponents to regionck.
-                    out.push(Component::Alias(alias_ty));
-                } else {
-                    // fallback case: hard code
-                    // OutlivesProjectionComponents. Continue walking
-                    // through and constrain Pi.
-                    let mut subcomponents = smallvec![];
-                    let mut subvisited = SsoHashSet::new();
-                    compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited);
-                    out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
-                }
-            }
-
-            // We assume that inference variables are fully resolved.
-            // So, if we encounter an inference variable, just record
-            // the unresolved variable as a component.
-            ty::Infer(infer_ty) => {
-                out.push(Component::UnresolvedInferenceVariable(infer_ty));
-            }
-
-            // Most types do not introduce any region binders, nor
-            // involve any other subtle cases, and so the WF relation
-            // simply constraints any regions referenced directly by
-            // the type and then visits the types that are lexically
-            // contained within. (The comments refer to relevant rules
-            // from RFC1214.)
-            ty::Bool |            // OutlivesScalar
-            ty::Char |            // OutlivesScalar
-            ty::Int(..) |         // OutlivesScalar
-            ty::Uint(..) |        // OutlivesScalar
-            ty::Float(..) |       // OutlivesScalar
-            ty::Never |           // ...
-            ty::Adt(..) |         // OutlivesNominalType
-            ty::Foreign(..) |     // OutlivesNominalType
-            ty::Str |             // OutlivesScalar (ish)
-            ty::Slice(..) |       // ...
-            ty::RawPtr(..) |      // ...
-            ty::Ref(..) |         // OutlivesReference
-            ty::Tuple(..) |       // ...
-            ty::FnPtr(_) |        // OutlivesFunction (*)
-            ty::Dynamic(..) |     // OutlivesObject, OutlivesFragment (*)
-            ty::Bound(..) |
-            ty::Error(_) => {
-                // (*) Function pointers and trait objects are both binders.
-                // In the RFC, this means we would add the bound regions to
-                // the "bound regions list". In our representation, no such
-                // list is maintained explicitly, because bound regions
-                // themselves can be readily identified.
-                compute_components_recursive(tcx, ty.into(), out, visited);
-            }
-        }
-}
-
-/// Collect [Component]s for *all* the args of `parent`.
-///
-/// This should not be used to get the components of `parent` itself.
-/// Use [push_outlives_components] instead.
-pub(super) fn compute_alias_components_recursive<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    alias_ty: Ty<'tcx>,
-    out: &mut SmallVec<[Component<'tcx>; 4]>,
-    visited: &mut SsoHashSet<GenericArg<'tcx>>,
-) {
-    let ty::Alias(kind, alias_ty) = alias_ty.kind() else {
-        unreachable!("can only call `compute_alias_components_recursive` on an alias type")
-    };
-    let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] };
-    for (index, child) in alias_ty.args.iter().enumerate() {
-        if opt_variances.get(index) == Some(&ty::Bivariant) {
-            continue;
-        }
-        if !visited.insert(child) {
-            continue;
-        }
-        match child.unpack() {
-            GenericArgKind::Type(ty) => {
-                compute_components(tcx, ty, out, visited);
-            }
-            GenericArgKind::Lifetime(lt) => {
-                // Ignore higher ranked regions.
-                if !lt.is_bound() {
-                    out.push(Component::Region(lt));
-                }
-            }
-            GenericArgKind::Const(_) => {
-                compute_components_recursive(tcx, child, out, visited);
-            }
-        }
-    }
-}
-
-/// Collect [Component]s for *all* the args of `parent`.
-///
-/// This should not be used to get the components of `parent` itself.
-/// Use [push_outlives_components] instead.
-fn compute_components_recursive<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    parent: GenericArg<'tcx>,
-    out: &mut SmallVec<[Component<'tcx>; 4]>,
-    visited: &mut SsoHashSet<GenericArg<'tcx>>,
-) {
-    for child in parent.walk_shallow(visited) {
-        match child.unpack() {
-            GenericArgKind::Type(ty) => {
-                compute_components(tcx, ty, out, visited);
-            }
-            GenericArgKind::Lifetime(lt) => {
-                // Ignore higher ranked regions.
-                if !lt.is_bound() {
-                    out.push(Component::Region(lt));
-                }
-            }
-            GenericArgKind::Const(_) => {
-                compute_components_recursive(tcx, child, out, visited);
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 48d006e7fbc..89ff4604560 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -8,7 +8,6 @@ use crate::infer::lexical_region_resolve;
 use rustc_middle::traits::query::{NoSolution, OutlivesBound};
 use rustc_middle::ty;
 
-pub mod components;
 pub mod env;
 pub mod for_liveness;
 pub mod obligations;
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 32c790523b6..d82ae7b4fb8 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -59,7 +59,6 @@
 //! might later infer `?U` to something like `&'b u32`, which would
 //! imply that `'b: 'a`.
 
-use crate::infer::outlives::components::{push_outlives_components, Component};
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::outlives::verify::VerifyBoundCx;
 use crate::infer::resolve::OpportunisticRegionResolver;
@@ -75,6 +74,7 @@ use rustc_middle::ty::{
 };
 use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
 use rustc_span::DUMMY_SP;
+use rustc_type_ir::outlives::{push_outlives_components, Component};
 use smallvec::smallvec;
 
 use super::env::OutlivesEnvironment;
@@ -291,7 +291,7 @@ where
     fn components_must_outlive(
         &mut self,
         origin: infer::SubregionOrigin<'tcx>,
-        components: &[Component<'tcx>],
+        components: &[Component<TyCtxt<'tcx>>],
         region: ty::Region<'tcx>,
         category: ConstraintCategory<'tcx>,
     ) {
@@ -471,7 +471,7 @@ where
         // projection outlive; in some cases, this may add insufficient
         // edges into the inference graph, leading to inference failures
         // even though a satisfactory solution exists.
-        let verify_bound = self.verify_bound.alias_bound(alias_ty, &mut Default::default());
+        let verify_bound = self.verify_bound.alias_bound(alias_ty);
         debug!("alias_must_outlive: pushing {:?}", verify_bound);
         self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound);
     }
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 7e977b9b954..2392a82025a 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -1,10 +1,8 @@
-use crate::infer::outlives::components::{compute_alias_components_recursive, Component};
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::region_constraints::VerifyIfEq;
 use crate::infer::{GenericKind, VerifyBound};
-use rustc_data_structures::sso::SsoHashSet;
-use rustc_middle::ty::GenericArg;
 use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
+use rustc_type_ir::outlives::{compute_alias_components_recursive, Component};
 
 use smallvec::smallvec;
 
@@ -99,12 +97,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty)
     }
 
-    #[instrument(level = "debug", skip(self, visited))]
-    pub fn alias_bound(
-        &self,
-        alias_ty: ty::AliasTy<'tcx>,
-        visited: &mut SsoHashSet<GenericArg<'tcx>>,
-    ) -> VerifyBound<'tcx> {
+    #[instrument(level = "debug", skip(self))]
+    pub fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> {
         let alias_ty_as_ty = alias_ty.to_ty(self.tcx);
 
         // Search the env for where clauses like `P: 'a`.
@@ -130,21 +124,17 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // see the extensive comment in projection_must_outlive
         let recursive_bound = {
             let mut components = smallvec![];
-            compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components, visited);
-            self.bound_from_components(&components, visited)
+            compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components);
+            self.bound_from_components(&components)
         };
 
         VerifyBound::AnyBound(env_bounds.chain(definition_bounds).collect()).or(recursive_bound)
     }
 
-    fn bound_from_components(
-        &self,
-        components: &[Component<'tcx>],
-        visited: &mut SsoHashSet<GenericArg<'tcx>>,
-    ) -> VerifyBound<'tcx> {
+    fn bound_from_components(&self, components: &[Component<TyCtxt<'tcx>>]) -> VerifyBound<'tcx> {
         let mut bounds = components
             .iter()
-            .map(|component| self.bound_from_single_component(component, visited))
+            .map(|component| self.bound_from_single_component(component))
             // Remove bounds that must hold, since they are not interesting.
             .filter(|bound| !bound.must_hold());
 
@@ -158,8 +148,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
 
     fn bound_from_single_component(
         &self,
-        component: &Component<'tcx>,
-        visited: &mut SsoHashSet<GenericArg<'tcx>>,
+        component: &Component<TyCtxt<'tcx>>,
     ) -> VerifyBound<'tcx> {
         match *component {
             Component::Region(lt) => VerifyBound::OutlivedBy(lt),
@@ -167,10 +156,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
             Component::Placeholder(placeholder_ty) => {
                 self.param_or_placeholder_bound(Ty::new_placeholder(self.tcx, placeholder_ty))
             }
-            Component::Alias(alias_ty) => self.alias_bound(alias_ty, visited),
-            Component::EscapingAlias(ref components) => {
-                self.bound_from_components(components, visited)
-            }
+            Component::Alias(alias_ty) => self.alias_bound(alias_ty),
+            Component::EscapingAlias(ref components) => self.bound_from_components(components),
             Component::UnresolvedInferenceVariable(v) => {
                 // Ignore this, we presume it will yield an error later, since
                 // if a type variable is not resolved by this point it never
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 0a2e85cc891..c93b89756f9 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -18,11 +18,13 @@
 //! On success, the  LUB/GLB operations return the appropriate bound. The
 //! return value of `Equate` or `Sub` shouldn't really be used.
 
+pub use rustc_next_trait_solver::relate::combine::*;
+
 use super::glb::Glb;
 use super::lub::Lub;
 use super::type_relating::TypeRelating;
+use super::RelateResult;
 use super::StructurallyRelateAliases;
-use super::{RelateResult, TypeRelation};
 use crate::infer::relate;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligation};
@@ -32,7 +34,6 @@ use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
 use rustc_middle::ty::{IntType, UintType};
-use rustc_span::Span;
 
 #[derive(Clone)]
 pub struct CombineFields<'infcx, 'tcx> {
@@ -76,7 +77,7 @@ impl<'tcx> InferCtxt<'tcx> {
         b: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
-        R: PredicateEmittingRelation<'tcx>,
+        R: PredicateEmittingRelation<InferCtxt<'tcx>>,
     {
         debug_assert!(!a.has_escaping_bound_vars());
         debug_assert!(!b.has_escaping_bound_vars());
@@ -171,7 +172,7 @@ impl<'tcx> InferCtxt<'tcx> {
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>>
     where
-        R: PredicateEmittingRelation<'tcx>,
+        R: PredicateEmittingRelation<InferCtxt<'tcx>>,
     {
         debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
         debug_assert!(!a.has_escaping_bound_vars());
@@ -323,30 +324,3 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         )
     }
 }
-
-pub trait PredicateEmittingRelation<'tcx>: TypeRelation<TyCtxt<'tcx>> {
-    fn span(&self) -> Span;
-
-    fn param_env(&self) -> ty::ParamEnv<'tcx>;
-
-    /// Whether aliases should be related structurally. This is pretty much
-    /// always `No` unless you're equating in some specific locations of the
-    /// new solver. See the comments in these use-cases for more details.
-    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases;
-
-    /// Register obligations that must hold in order for this relation to hold
-    fn register_goals(
-        &mut self,
-        obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
-    );
-
-    /// Register predicates that must hold in order for this relation to hold.
-    /// This uses the default `param_env` of the obligation.
-    fn register_predicates(
-        &mut self,
-        obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
-    );
-
-    /// Register `AliasRelate` obligation(s) that both types must be related to each other.
-    fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
-}
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index d6e57d85387..fe3b8d60fb9 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -30,7 +30,7 @@ impl<'tcx> InferCtxt<'tcx> {
     /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
     /// other usecases (i.e. setting the value of a type var).
     #[instrument(level = "debug", skip(self, relation))]
-    pub fn instantiate_ty_var<R: PredicateEmittingRelation<'tcx>>(
+    pub fn instantiate_ty_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
         &self,
         relation: &mut R,
         target_is_expected: bool,
@@ -178,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
     #[instrument(level = "debug", skip(self, relation))]
-    pub(super) fn instantiate_const_var<R: PredicateEmittingRelation<'tcx>>(
+    pub(super) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
         &self,
         relation: &mut R,
         target_is_expected: bool,
diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 067004ecaeb..5bb8a113e17 100644
--- a/compiler/rustc_infer/src/infer/relate/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -123,7 +123,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
     }
 }
 
-impl<'tcx> PredicateEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 6cc8d6d910a..46e7466141a 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Ty};
 ///
 /// GLB moves "down" the lattice (to smaller values); LUB moves
 /// "up" the lattice (to bigger values).
-pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<'tcx> {
+pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<InferCtxt<'tcx>> {
     fn infcx(&self) -> &'f InferCtxt<'tcx>;
 
     fn cause(&self) -> &ObligationCause<'tcx>;
diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index 2184416b4cc..94c1464817f 100644
--- a/compiler/rustc_infer/src/infer/relate/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -123,7 +123,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
     }
 }
 
-impl<'tcx> PredicateEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index 41cc945492d..dd97dc061fe 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -2,11 +2,13 @@
 //! (except for some relations used for diagnostics and heuristics in the compiler).
 //! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc).
 
-pub use rustc_middle::ty::relate::*;
+pub use rustc_middle::ty::relate::RelateResult;
+pub use rustc_next_trait_solver::relate::*;
 
 pub use self::combine::CombineFields;
 pub use self::combine::PredicateEmittingRelation;
 
+#[allow(hidden_glob_reexports)]
 pub(super) mod combine;
 mod generalize;
 mod glb;
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index f2bec9392d5..e206f530519 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -1,7 +1,7 @@
 use super::combine::CombineFields;
 use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
 use crate::infer::BoundRegionConversionTime::HigherRankedType;
-use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
+use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use rustc_middle::traits::solve::Goal;
 use rustc_middle::ty::relate::{
     relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation,
@@ -296,7 +296,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
     }
 }
 
-impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
+impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
     fn span(&self) -> Span {
         self.fields.trace.span()
     }
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 24cf9f03fcd..b269bfcbfeb 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -1,11 +1,12 @@
 use smallvec::smallvec;
 
-use crate::infer::outlives::components::{push_outlives_components, Component};
 use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_middle::ty::ToPolyTraitRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
 use rustc_span::symbol::Ident;
 use rustc_span::Span;
+use rustc_type_ir::outlives::{push_outlives_components, Component};
 
 pub fn anonymize_predicate<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> {
 enum Filter {
     All,
     OnlySelf,
-    OnlySelfThatDefines(Ident),
 }
 
 /// Describes how to elaborate an obligation into a sub-obligation.
@@ -252,12 +252,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
         self
     }
 
-    /// Filter to only the supertraits of trait predicates that define the assoc_ty.
-    pub fn filter_only_self_that_defines(mut self, assoc_ty: Ident) -> Self {
-        self.mode = Filter::OnlySelfThatDefines(assoc_ty);
-        self
-    }
-
     fn elaborate(&mut self, elaboratable: &O) {
         let tcx = self.visited.tcx;
 
@@ -277,9 +271,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
                 let predicates = match self.mode {
                     Filter::All => tcx.explicit_implied_predicates_of(data.def_id()),
                     Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()),
-                    Filter::OnlySelfThatDefines(ident) => {
-                        tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident))
-                    }
                 };
 
                 let obligations =
@@ -405,14 +396,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> {
 pub fn supertraits<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
-) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
+) -> FilterToTraits<Elaborator<'tcx, ty::Clause<'tcx>>> {
     elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits()
 }
 
 pub fn transitive_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
+) -> FilterToTraits<Elaborator<'tcx, ty::Clause<'tcx>>> {
     elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx)))
         .filter_only_self()
         .filter_to_traits()
@@ -427,17 +418,37 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
     assoc_name: Ident,
-) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
-    elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx)))
-        .filter_only_self_that_defines(assoc_name)
-        .filter_to_traits()
+) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
+    let mut seen = FxHashSet::default();
+    let mut stack: Vec<_> = trait_refs.collect();
+
+    std::iter::from_fn(move || {
+        while let Some(trait_ref) = stack.pop() {
+            if !seen.insert(tcx.anonymize_bound_vars(trait_ref)) {
+                continue;
+            }
+
+            stack.extend(
+                tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name))
+                    .instantiate_own_identity()
+                    .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
+                    .filter_map(|clause| clause.as_trait_clause())
+                    // FIXME: Negative supertraits are elaborated here lol
+                    .map(|trait_pred| trait_pred.to_poly_trait_ref()),
+            );
+
+            return Some(trait_ref);
+        }
+
+        None
+    })
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // Other
 ///////////////////////////////////////////////////////////////////////////
 
-impl<'tcx> Elaborator<'tcx, ty::Predicate<'tcx>> {
+impl<'tcx> Elaborator<'tcx, ty::Clause<'tcx>> {
     fn filter_to_traits(self) -> FilterToTraits<Self> {
         FilterToTraits { base_iterator: self }
     }
@@ -449,7 +460,7 @@ pub struct FilterToTraits<I> {
     base_iterator: I,
 }
 
-impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
+impl<'tcx, I: Iterator<Item = ty::Clause<'tcx>>> Iterator for FilterToTraits<I> {
     type Item = ty::PolyTraitRef<'tcx>;
 
     fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
index c69e680cb64..da36f68fca9 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
@@ -261,10 +261,16 @@ pub(super) fn unexpected_cfg_value(
         lints::unexpected_cfg_value::CodeSuggestion::RemoveCondition { suggestion, name }
     };
 
-    // We don't want to suggest adding values to well known names
-    // since those are defined by rustc it-self. Users can still
-    // do it if they want, but should not encourage them.
-    let is_cfg_a_well_know_name = sess.psess.check_config.well_known_names.contains(&name);
+    // We don't want to encourage people to add values to a well-known names, as these are
+    // defined by rustc/Rust itself. Users can still do this if they wish, but should not be
+    // encouraged to do so.
+    let can_suggest_adding_value = !sess.psess.check_config.well_known_names.contains(&name)
+        // Except when working on rustc or the standard library itself, in which case we want to
+        // suggest adding these cfgs to the "normal" place because of bootstraping reasons. As a
+        // basic heuristic, we use the "cheat" unstable feature enable method and the
+        // non-ui-testing enabled option.
+        || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat)
+            && !sess.opts.unstable_opts.ui_testing);
 
     let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);
 
@@ -275,14 +281,14 @@ pub(super) fn unexpected_cfg_value(
             } else {
                 Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures)
             }
-        } else if !is_cfg_a_well_know_name {
+        } else if can_suggest_adding_value {
             Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst)))
         } else {
             None
         };
         lints::unexpected_cfg_value::InvocationHelp::Cargo(help)
     } else {
-        let help = if !is_cfg_a_well_know_name {
+        let help = if can_suggest_adding_value {
             Some(lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No)))
         } else {
             None
diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs
index e7d0cffc85c..a3aff9a1101 100644
--- a/compiler/rustc_middle/src/middle/dependency_format.rs
+++ b/compiler/rustc_middle/src/middle/dependency_format.rs
@@ -4,15 +4,15 @@
 //! For all the gory details, see the provider of the `dependency_formats`
 //! query.
 
+// FIXME: move this file to rustc_metadata::dependency_format, but
+// this will introduce circular dependency between rustc_metadata and rustc_middle
+
 use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_session::config::CrateType;
 
 /// A list of dependencies for a certain crate type.
 ///
 /// The length of this vector is the same as the number of external crates used.
-/// The value is None if the crate does not need to be linked (it was found
-/// statically in another dylib), or Some(kind) if it needs to be linked as
-/// `kind` (either static or dynamic).
 pub type DependencyList = Vec<Linkage>;
 
 /// A mapping of all required dependencies for a particular flavor of output.
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index da25fbb0a82..beaaadd497d 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -103,7 +103,7 @@ pub enum CoverageKind {
     SpanMarker,
 
     /// Marks its enclosing basic block with an ID that can be referred to by
-    /// side data in [`BranchInfo`].
+    /// side data in [`CoverageInfoHi`].
     ///
     /// Should be erased before codegen (at some point after `InstrumentCoverage`).
     BlockMarker { id: BlockMarkerId },
@@ -274,10 +274,15 @@ pub struct FunctionCoverageInfo {
     pub mcdc_num_condition_bitmaps: usize,
 }
 
-/// Branch information recorded during THIR-to-MIR lowering, and stored in MIR.
+/// Coverage information for a function, recorded during MIR building and
+/// attached to the corresponding `mir::Body`. Used by the `InstrumentCoverage`
+/// MIR pass.
+///
+/// ("Hi" indicates that this is "high-level" information collected at the
+/// THIR/MIR boundary, before the MIR-based coverage instrumentation pass.)
 #[derive(Clone, Debug)]
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
-pub struct BranchInfo {
+pub struct CoverageInfoHi {
     /// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was
     /// injected into the MIR body. This makes it possible to allocate per-ID
     /// data structures without having to scan the entire body first.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index ef88b253864..83e3898cebf 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -430,11 +430,12 @@ pub struct Body<'tcx> {
 
     pub tainted_by_errors: Option<ErrorGuaranteed>,
 
-    /// Branch coverage information collected during MIR building, to be used by
-    /// the `InstrumentCoverage` pass.
+    /// Coverage information collected from THIR/MIR during MIR building,
+    /// to be used by the `InstrumentCoverage` pass.
     ///
-    /// Only present if branch coverage is enabled and this function is eligible.
-    pub coverage_branch_info: Option<Box<coverage::BranchInfo>>,
+    /// Only present if coverage is enabled and this function is eligible.
+    /// Boxed to limit space overhead in non-coverage builds.
+    pub coverage_info_hi: Option<Box<coverage::CoverageInfoHi>>,
 
     /// Per-function coverage information added by the `InstrumentCoverage`
     /// pass, to be used in conjunction with the coverage statements injected
@@ -484,7 +485,7 @@ impl<'tcx> Body<'tcx> {
             is_polymorphic: false,
             injection_phase: None,
             tainted_by_errors,
-            coverage_branch_info: None,
+            coverage_info_hi: None,
             function_coverage_info: None,
         };
         body.is_polymorphic = body.has_non_region_param();
@@ -515,7 +516,7 @@ impl<'tcx> Body<'tcx> {
             is_polymorphic: false,
             injection_phase: None,
             tainted_by_errors: None,
-            coverage_branch_info: None,
+            coverage_info_hi: None,
             function_coverage_info: None,
         };
         body.is_polymorphic = body.has_non_region_param();
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 4453ce44b03..af19ed95193 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -473,8 +473,8 @@ pub fn write_mir_intro<'tcx>(
     // Add an empty line before the first block is printed.
     writeln!(w)?;
 
-    if let Some(branch_info) = &body.coverage_branch_info {
-        write_coverage_branch_info(branch_info, w)?;
+    if let Some(coverage_info_hi) = &body.coverage_info_hi {
+        write_coverage_info_hi(coverage_info_hi, w)?;
     }
     if let Some(function_coverage_info) = &body.function_coverage_info {
         write_function_coverage_info(function_coverage_info, w)?;
@@ -483,18 +483,26 @@ pub fn write_mir_intro<'tcx>(
     Ok(())
 }
 
-fn write_coverage_branch_info(
-    branch_info: &coverage::BranchInfo,
+fn write_coverage_info_hi(
+    coverage_info_hi: &coverage::CoverageInfoHi,
     w: &mut dyn io::Write,
 ) -> io::Result<()> {
-    let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
-        branch_info;
+    let coverage::CoverageInfoHi {
+        num_block_markers: _,
+        branch_spans,
+        mcdc_branch_spans,
+        mcdc_decision_spans,
+    } = coverage_info_hi;
+
+    // Only add an extra trailing newline if we printed at least one thing.
+    let mut did_print = false;
 
     for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
         writeln!(
             w,
             "{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
         )?;
+        did_print = true;
     }
 
     for coverage::MCDCBranchSpan {
@@ -510,6 +518,7 @@ fn write_coverage_branch_info(
             "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}",
             condition_info.map(|info| info.condition_id)
         )?;
+        did_print = true;
     }
 
     for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
@@ -519,10 +528,10 @@ fn write_coverage_branch_info(
             w,
             "{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
         )?;
+        did_print = true;
     }
 
-    if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
-    {
+    if did_print {
         writeln!(w)?;
     }
 
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index bf834ef7607..98f35b6b8ab 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -54,6 +54,13 @@ pub struct Expr<'tcx> {
     pub kind: ExprKind,
     args: ty::GenericArgsRef<'tcx>,
 }
+
+impl<'tcx> rustc_type_ir::inherent::ExprConst<TyCtxt<'tcx>> for Expr<'tcx> {
+    fn args(self) -> ty::GenericArgsRef<'tcx> {
+        self.args
+    }
+}
+
 impl<'tcx> Expr<'tcx> {
     pub fn new_binop(
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 055749ba3a3..dca48069974 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -92,6 +92,8 @@ use std::ops::{Bound, Deref};
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type DefId = DefId;
     type LocalDefId = LocalDefId;
+    type Span = Span;
+
     type GenericArgs = ty::GenericArgsRef<'tcx>;
 
     type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index b169d672a84..ebf0d7ed737 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -10,18 +10,6 @@ use crate::ty::{self as ty, Ty, TyCtxt};
 
 pub type RelateResult<'tcx, T> = rustc_type_ir::relate::RelateResult<TyCtxt<'tcx>, T>;
 
-/// Whether aliases should be related structurally or not. Used
-/// to adjust the behavior of generalization and combine.
-///
-/// This should always be `No` unless in a few special-cases when
-/// instantiating canonical responses and in the new solver. Each
-/// such case should have a comment explaining why it is used.
-#[derive(Debug, Copy, Clone)]
-pub enum StructurallyRelateAliases {
-    Yes,
-    No,
-}
-
 impl<'tcx> Relate<TyCtxt<'tcx>> for ty::ImplSubject<'tcx> {
     #[inline]
     fn relate<R: TypeRelation<TyCtxt<'tcx>>>(
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index e0f204a687f..efcaf89081f 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -78,23 +78,6 @@ impl<'tcx> GenericArg<'tcx> {
     pub fn walk(self) -> TypeWalker<'tcx> {
         TypeWalker::new(self)
     }
-
-    /// Iterator that walks the immediate children of `self`. Hence
-    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
-    /// (but not `i32`, like `walk`).
-    ///
-    /// Iterator only walks items once.
-    /// It accepts visited set, updates it with all visited types
-    /// and skips any types that are already there.
-    pub fn walk_shallow(
-        self,
-        visited: &mut SsoHashSet<GenericArg<'tcx>>,
-    ) -> impl Iterator<Item = GenericArg<'tcx>> {
-        let mut stack = SmallVec::new();
-        push_inner(&mut stack, self);
-        stack.retain(|a| visited.insert(*a));
-        stack.into_iter()
-    }
 }
 
 impl<'tcx> Ty<'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs
index 876faca5172..204ee45bfa2 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs
@@ -2,7 +2,7 @@ use std::assert_matches::assert_matches;
 use std::collections::hash_map::Entry;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind};
+use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind};
 use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
 use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir};
 use rustc_middle::ty::TyCtxt;
@@ -13,16 +13,25 @@ use crate::build::{Builder, CFG};
 
 mod mcdc;
 
-pub(crate) struct BranchInfoBuilder {
+/// Collects coverage-related information during MIR building, to eventually be
+/// turned into a function's [`CoverageInfoHi`] when MIR building is complete.
+pub(crate) struct CoverageInfoBuilder {
     /// Maps condition expressions to their enclosing `!`, for better instrumentation.
     nots: FxHashMap<ExprId, NotInfo>,
 
     markers: BlockMarkerGen,
-    branch_spans: Vec<BranchSpan>,
 
+    /// Present if branch coverage is enabled.
+    branch_info: Option<BranchInfo>,
+    /// Present if MC/DC coverage is enabled.
     mcdc_info: Option<MCDCInfoBuilder>,
 }
 
+#[derive(Default)]
+struct BranchInfo {
+    branch_spans: Vec<BranchSpan>,
+}
+
 #[derive(Clone, Copy)]
 struct NotInfo {
     /// When visiting the associated expression as a branch condition, treat this
@@ -62,20 +71,20 @@ impl BlockMarkerGen {
     }
 }
 
-impl BranchInfoBuilder {
-    /// Creates a new branch info builder, but only if branch coverage instrumentation
+impl CoverageInfoBuilder {
+    /// Creates a new coverage info builder, but only if coverage instrumentation
     /// is enabled and `def_id` represents a function that is eligible for coverage.
     pub(crate) fn new_if_enabled(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Self> {
-        if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) {
-            Some(Self {
-                nots: FxHashMap::default(),
-                markers: BlockMarkerGen::default(),
-                branch_spans: vec![],
-                mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new),
-            })
-        } else {
-            None
+        if !tcx.sess.instrument_coverage() || !tcx.is_eligible_for_coverage(def_id) {
+            return None;
         }
+
+        Some(Self {
+            nots: FxHashMap::default(),
+            markers: BlockMarkerGen::default(),
+            branch_info: tcx.sess.instrument_coverage_branch().then(BranchInfo::default),
+            mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new),
+        })
     }
 
     /// Unary `!` expressions inside an `if` condition are lowered by lowering
@@ -88,6 +97,12 @@ impl BranchInfoBuilder {
     pub(crate) fn visit_unary_not(&mut self, thir: &Thir<'_>, unary_not: ExprId) {
         assert_matches!(thir[unary_not].kind, ExprKind::Unary { op: UnOp::Not, .. });
 
+        // The information collected by this visitor is only needed when branch
+        // coverage or higher is enabled.
+        if self.branch_info.is_none() {
+            return;
+        }
+
         self.visit_with_not_info(
             thir,
             unary_not,
@@ -137,40 +152,40 @@ impl BranchInfoBuilder {
                 false_block,
                 inject_block_marker,
             );
-        } else {
-            let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
-            let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
-
-            self.branch_spans.push(BranchSpan {
-                span: source_info.span,
-                true_marker,
-                false_marker,
-            });
+            return;
         }
+
+        // Bail out if branch coverage is not enabled.
+        let Some(branch_info) = self.branch_info.as_mut() else { return };
+
+        let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
+        let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
+
+        branch_info.branch_spans.push(BranchSpan {
+            span: source_info.span,
+            true_marker,
+            false_marker,
+        });
     }
 
-    pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
-        let Self {
-            nots: _,
-            markers: BlockMarkerGen { num_block_markers },
-            branch_spans,
-            mcdc_info,
-        } = self;
+    pub(crate) fn into_done(self) -> Box<CoverageInfoHi> {
+        let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info, mcdc_info } =
+            self;
 
-        if num_block_markers == 0 {
-            assert!(branch_spans.is_empty());
-            return None;
-        }
+        let branch_spans =
+            branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default();
 
         let (mcdc_decision_spans, mcdc_branch_spans) =
             mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default();
 
-        Some(Box::new(mir::coverage::BranchInfo {
+        // For simplicity, always return an info struct (without Option), even
+        // if there's nothing interesting in it.
+        Box::new(CoverageInfoHi {
             num_block_markers,
             branch_spans,
             mcdc_branch_spans,
             mcdc_decision_spans,
-        }))
+        })
     }
 }
 
@@ -184,7 +199,7 @@ impl<'tcx> Builder<'_, 'tcx> {
         block: &mut BasicBlock,
     ) {
         // Bail out if condition coverage is not enabled for this function.
-        let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
+        let Some(coverage_info) = self.coverage_info.as_mut() else { return };
         if !self.tcx.sess.instrument_coverage_condition() {
             return;
         };
@@ -224,7 +239,7 @@ impl<'tcx> Builder<'_, 'tcx> {
         );
 
         // Separate path for handling branches when MC/DC is enabled.
-        branch_info.register_two_way_branch(
+        coverage_info.register_two_way_branch(
             self.tcx,
             &mut self.cfg,
             source_info,
@@ -247,12 +262,12 @@ impl<'tcx> Builder<'_, 'tcx> {
         mut then_block: BasicBlock,
         mut else_block: BasicBlock,
     ) {
-        // Bail out if branch coverage is not enabled for this function.
-        let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
+        // Bail out if coverage is not enabled for this function.
+        let Some(coverage_info) = self.coverage_info.as_mut() else { return };
 
         // If this condition expression is nested within one or more `!` expressions,
         // replace it with the enclosing `!` collected by `visit_unary_not`.
-        if let Some(&NotInfo { enclosing_not, is_flipped }) = branch_info.nots.get(&expr_id) {
+        if let Some(&NotInfo { enclosing_not, is_flipped }) = coverage_info.nots.get(&expr_id) {
             expr_id = enclosing_not;
             if is_flipped {
                 std::mem::swap(&mut then_block, &mut else_block);
@@ -261,7 +276,7 @@ impl<'tcx> Builder<'_, 'tcx> {
 
         let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
 
-        branch_info.register_two_way_branch(
+        coverage_info.register_two_way_branch(
             self.tcx,
             &mut self.cfg,
             source_info,
@@ -280,13 +295,11 @@ impl<'tcx> Builder<'_, 'tcx> {
         true_block: BasicBlock,
         false_block: BasicBlock,
     ) {
-        // Bail out if branch coverage is not enabled for this function.
-        let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
-
-        // FIXME(#124144) This may need special handling when MC/DC is enabled.
+        // Bail out if coverage is not enabled for this function.
+        let Some(coverage_info) = self.coverage_info.as_mut() else { return };
 
         let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
-        branch_info.register_two_way_branch(
+        coverage_info.register_two_way_branch(
             self.tcx,
             &mut self.cfg,
             source_info,
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
index f97e9ef60a2..3aa6e708476 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
@@ -250,24 +250,24 @@ impl MCDCInfoBuilder {
 
 impl Builder<'_, '_> {
     pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
-        if let Some(branch_info) = self.coverage_branch_info.as_mut()
-            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        if let Some(coverage_info) = self.coverage_info.as_mut()
+            && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
         {
             mcdc_info.state.record_conditions(logical_op, span);
         }
     }
 
     pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) {
-        if let Some(branch_info) = self.coverage_branch_info.as_mut()
-            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        if let Some(coverage_info) = self.coverage_info.as_mut()
+            && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
         {
             mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default());
         };
     }
 
     pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) {
-        if let Some(branch_info) = self.coverage_branch_info.as_mut()
-            && let Some(mcdc_info) = branch_info.mcdc_info.as_mut()
+        if let Some(coverage_info) = self.coverage_info.as_mut()
+            && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut()
         {
             if mcdc_info.state.decision_ctx_stack.pop().is_none() {
                 bug!("Unexpected empty decision stack");
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index a0a512a2eff..f6ebcbcbdc9 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -62,7 +62,7 @@ pub(super) fn build_custom_mir<'tcx>(
         tainted_by_errors: None,
         injection_phase: None,
         pass_count: 0,
-        coverage_branch_info: None,
+        coverage_info_hi: None,
         function_coverage_info: None,
     };
 
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index efed52231e3..e435e2f9288 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -160,8 +160,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // Improve branch coverage instrumentation by noting conditions
                 // nested within one or more `!` expressions.
                 // (Skipped if branch coverage is not enabled.)
-                if let Some(branch_info) = this.coverage_branch_info.as_mut() {
-                    branch_info.visit_unary_not(this.thir, expr_id);
+                if let Some(coverage_info) = this.coverage_info.as_mut() {
+                    coverage_info.visit_unary_not(this.thir, expr_id);
                 }
 
                 let local_scope = this.local_scope();
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 601e5d4d3dc..0f9746cb719 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -218,8 +218,8 @@ struct Builder<'a, 'tcx> {
     lint_level_roots_cache: GrowableBitSet<hir::ItemLocalId>,
 
     /// Collects additional coverage information during MIR building.
-    /// Only present if branch coverage is enabled and this function is eligible.
-    coverage_branch_info: Option<coverageinfo::BranchInfoBuilder>,
+    /// Only present if coverage is enabled and this function is eligible.
+    coverage_info: Option<coverageinfo::CoverageInfoBuilder>,
 }
 
 type CaptureMap<'tcx> = SortedIndexMultiMap<usize, HirId, Capture<'tcx>>;
@@ -773,7 +773,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             unit_temp: None,
             var_debug_info: vec![],
             lint_level_roots_cache: GrowableBitSet::new_empty(),
-            coverage_branch_info: coverageinfo::BranchInfoBuilder::new_if_enabled(tcx, def),
+            coverage_info: coverageinfo::CoverageInfoBuilder::new_if_enabled(tcx, def),
         };
 
         assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
@@ -802,7 +802,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.coroutine,
             None,
         );
-        body.coverage_branch_info = self.coverage_branch_info.and_then(|b| b.into_done());
+        body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
         body
     }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index 235992ac547..25297245172 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -3,7 +3,9 @@ use std::collections::BTreeSet;
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
-use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind};
+use rustc_middle::mir::coverage::{
+    BlockMarkerId, BranchSpan, ConditionInfo, CoverageInfoHi, CoverageKind,
+};
 use rustc_middle::mir::{self, BasicBlock, StatementKind};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
@@ -157,12 +159,12 @@ impl ExtractedMappings {
 }
 
 fn resolve_block_markers(
-    branch_info: &mir::coverage::BranchInfo,
+    coverage_info_hi: &CoverageInfoHi,
     mir_body: &mir::Body<'_>,
 ) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
     let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
         None,
-        branch_info.num_block_markers,
+        coverage_info_hi.num_block_markers,
     );
 
     // Fill out the mapping from block marker IDs to their enclosing blocks.
@@ -188,11 +190,11 @@ pub(super) fn extract_branch_pairs(
     hir_info: &ExtractedHirInfo,
     basic_coverage_blocks: &CoverageGraph,
 ) -> Vec<BranchPair> {
-    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] };
+    let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] };
 
-    let block_markers = resolve_block_markers(branch_info, mir_body);
+    let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
 
-    branch_info
+    coverage_info_hi
         .branch_spans
         .iter()
         .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
@@ -222,9 +224,9 @@ pub(super) fn extract_mcdc_mappings(
     mcdc_branches: &mut impl Extend<MCDCBranch>,
     mcdc_decisions: &mut impl Extend<MCDCDecision>,
 ) {
-    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return };
+    let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return };
 
-    let block_markers = resolve_block_markers(branch_info, mir_body);
+    let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
 
     let bcb_from_marker =
         |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
@@ -243,7 +245,7 @@ pub(super) fn extract_mcdc_mappings(
             Some((span, true_bcb, false_bcb))
         };
 
-    mcdc_branches.extend(branch_info.mcdc_branch_spans.iter().filter_map(
+    mcdc_branches.extend(coverage_info_hi.mcdc_branch_spans.iter().filter_map(
         |&mir::coverage::MCDCBranchSpan {
              span: raw_span,
              condition_info,
@@ -257,7 +259,7 @@ pub(super) fn extract_mcdc_mappings(
         },
     ));
 
-    mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map(
+    mcdc_decisions.extend(coverage_info_hi.mcdc_decision_spans.iter().filter_map(
         |decision: &mir::coverage::MCDCDecisionSpan| {
             let span = unexpand_into_body_span(decision.span, body_span)?;
 
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index fbbb8c5e472..25bebb0539a 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -33,16 +33,16 @@ use std::fmt;
 /// as it would allow running a destructor on a place behind a reference:
 ///
 /// ```text
-// fn drop_term<T>(t: &mut T) {
-//     mir! {
-//         {
-//             Drop(*t, exit)
-//         }
-//         exit = {
-//             Return()
-//         }
-//     }
-// }
+/// fn drop_term<T>(t: &mut T) {
+///     mir! {
+///         {
+///             Drop(*t, exit)
+///         }
+///         exit = {
+///             Return()
+///         }
+///     }
+/// }
 /// ```
 pub struct ElaborateDrops;
 
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 695d02705ab..82488088e30 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -4,7 +4,8 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::visit::TypeVisitableExt;
 use rustc_type_ir::{
-    self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Interner,
+    self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike,
+    Interner,
 };
 
 use crate::delegate::SolverDelegate;
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index 6626acfe963..31032dc679a 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -1,18 +1,20 @@
 use std::fmt::Debug;
+use std::ops::Deref;
 
 use rustc_type_ir::fold::TypeFoldable;
-use rustc_type_ir::relate::Relate;
 use rustc_type_ir::solve::{Certainty, Goal, NoSolution, SolverMode};
-use rustc_type_ir::{self as ty, Interner};
+use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
 
-pub trait SolverDelegate: Sized {
+pub trait SolverDelegate:
+    Deref<Target: InferCtxtLike<Interner = <Self as SolverDelegate>::Interner>> + Sized
+{
     type Interner: Interner;
-    fn cx(&self) -> Self::Interner;
+    fn cx(&self) -> Self::Interner {
+        (**self).cx()
+    }
 
     type Span: Copy;
 
-    fn solver_mode(&self) -> SolverMode;
-
     fn build_with_canonical<V>(
         cx: Self::Interner,
         solver_mode: SolverMode,
@@ -21,82 +23,12 @@ pub trait SolverDelegate: Sized {
     where
         V: TypeFoldable<Self::Interner>;
 
-    fn universe(&self) -> ty::UniverseIndex;
-    fn create_next_universe(&self) -> ty::UniverseIndex;
-
-    fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
-    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
-    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
-
-    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
-    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
-
-    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
-    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
-    fn opportunistic_resolve_float_var(
-        &self,
-        vid: ty::FloatVid,
-    ) -> <Self::Interner as Interner>::Ty;
-    fn opportunistic_resolve_ct_var(
-        &self,
-        vid: ty::ConstVid,
-    ) -> <Self::Interner as Interner>::Const;
-    fn opportunistic_resolve_effect_var(
-        &self,
-        vid: ty::EffectVid,
-    ) -> <Self::Interner as Interner>::Const;
-    fn opportunistic_resolve_lt_var(
-        &self,
-        vid: ty::RegionVid,
-    ) -> <Self::Interner as Interner>::Region;
-
-    fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes;
-
-    fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
-    fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
-    fn fresh_args_for_item(
-        &self,
-        def_id: <Self::Interner as Interner>::DefId,
-    ) -> <Self::Interner as Interner>::GenericArgs;
-
     fn fresh_var_for_kind_with_span(
         &self,
         arg: <Self::Interner as Interner>::GenericArg,
         span: Self::Span,
     ) -> <Self::Interner as Interner>::GenericArg;
 
-    fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
-        &self,
-        value: ty::Binder<Self::Interner, T>,
-    ) -> T;
-
-    fn enter_forall<T: TypeFoldable<Self::Interner> + Copy, U>(
-        &self,
-        value: ty::Binder<Self::Interner, T>,
-        f: impl FnOnce(T) -> U,
-    ) -> U;
-
-    fn relate<T: Relate<Self::Interner>>(
-        &self,
-        param_env: <Self::Interner as Interner>::ParamEnv,
-        lhs: T,
-        variance: ty::Variance,
-        rhs: T,
-    ) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>;
-
-    fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>(
-        &self,
-        param_env: <Self::Interner as Interner>::ParamEnv,
-        lhs: T,
-        rhs: T,
-    ) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>;
-
-    fn resolve_vars_if_possible<T>(&self, value: T) -> T
-    where
-        T: TypeFoldable<Self::Interner>;
-
-    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
-
     // FIXME: Uplift the leak check into this crate.
     fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>;
 
@@ -112,18 +44,6 @@ pub trait SolverDelegate: Sized {
         unevaluated: ty::UnevaluatedConst<Self::Interner>,
     ) -> Option<<Self::Interner as Interner>::Const>;
 
-    fn sub_regions(
-        &self,
-        sub: <Self::Interner as Interner>::Region,
-        sup: <Self::Interner as Interner>::Region,
-    );
-
-    fn register_ty_outlives(
-        &self,
-        ty: <Self::Interner as Interner>::Ty,
-        r: <Self::Interner as Interner>::Region,
-    );
-
     // FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`!
     fn well_formed_goals(
         &self,
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index a6a9c01faaa..761475d3d6b 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -6,5 +6,6 @@
 
 pub mod canonicalizer;
 pub mod delegate;
+pub mod relate;
 pub mod resolve;
 pub mod solve;
diff --git a/compiler/rustc_next_trait_solver/src/relate.rs b/compiler/rustc_next_trait_solver/src/relate.rs
new file mode 100644
index 00000000000..db819961bbd
--- /dev/null
+++ b/compiler/rustc_next_trait_solver/src/relate.rs
@@ -0,0 +1,15 @@
+pub use rustc_type_ir::relate::*;
+
+pub mod combine;
+
+/// Whether aliases should be related structurally or not. Used
+/// to adjust the behavior of generalization and combine.
+///
+/// This should always be `No` unless in a few special-cases when
+/// instantiating canonical responses and in the new solver. Each
+/// such case should have a comment explaining why it is used.
+#[derive(Debug, Copy, Clone)]
+pub enum StructurallyRelateAliases {
+    Yes,
+    No,
+}
diff --git a/compiler/rustc_next_trait_solver/src/relate/combine.rs b/compiler/rustc_next_trait_solver/src/relate/combine.rs
new file mode 100644
index 00000000000..96968327d8e
--- /dev/null
+++ b/compiler/rustc_next_trait_solver/src/relate/combine.rs
@@ -0,0 +1,34 @@
+pub use rustc_type_ir::relate::*;
+use rustc_type_ir::solve::Goal;
+use rustc_type_ir::{InferCtxtLike, Interner, Upcast};
+
+use super::StructurallyRelateAliases;
+
+pub trait PredicateEmittingRelation<Infcx, I = <Infcx as InferCtxtLike>::Interner>:
+    TypeRelation<I>
+where
+    Infcx: InferCtxtLike<Interner = I>,
+    I: Interner,
+{
+    fn span(&self) -> I::Span;
+
+    fn param_env(&self) -> I::ParamEnv;
+
+    /// Whether aliases should be related structurally. This is pretty much
+    /// always `No` unless you're equating in some specific locations of the
+    /// new solver. See the comments in these use-cases for more details.
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases;
+
+    /// Register obligations that must hold in order for this relation to hold
+    fn register_goals(&mut self, obligations: impl IntoIterator<Item = Goal<I, I::Predicate>>);
+
+    /// Register predicates that must hold in order for this relation to hold.
+    /// This uses the default `param_env` of the obligation.
+    fn register_predicates(
+        &mut self,
+        obligations: impl IntoIterator<Item: Upcast<I, I::Predicate>>,
+    );
+
+    /// Register `AliasRelate` obligation(s) that both types must be related to each other.
+    fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty);
+}
diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs
index 6ed58d0e4fb..254ee514f8b 100644
--- a/compiler/rustc_next_trait_solver/src/resolve.rs
+++ b/compiler/rustc_next_trait_solver/src/resolve.rs
@@ -2,7 +2,7 @@ use crate::delegate::SolverDelegate;
 use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::visit::TypeVisitableExt;
-use rustc_type_ir::{self as ty, Interner};
+use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
 
 ///////////////////////////////////////////////////////////////////////////
 // EAGER RESOLUTION
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 0a313c6a951..9474d501d6f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -14,7 +14,7 @@ use std::iter;
 use rustc_index::IndexVec;
 use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::inherent::*;
-use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, Interner};
+use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner};
 use tracing::{instrument, trace};
 
 use crate::canonicalizer::{CanonicalizeMode, Canonicalizer};
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 87342eefb33..d8a3acc655a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -7,7 +7,7 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::relate::Relate;
 use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
-use rustc_type_ir::{self as ty, CanonicalVarValues, Interner};
+use rustc_type_ir::{self as ty, CanonicalVarValues, InferCtxtLike, Interner};
 use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
 use tracing::{instrument, trace};
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
index e9516c60c70..4258dd9263a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs
@@ -1,6 +1,6 @@
 use std::marker::PhantomData;
 
-use rustc_type_ir::Interner;
+use rustc_type_ir::{InferCtxtLike, Interner};
 use tracing::instrument;
 
 use crate::delegate::SolverDelegate;
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 6ea0ed339a6..55514883cb1 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -277,7 +277,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         pats: &[hir::PatField<'_>],
     ) {
         let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
-            ty::Adt(adt, _) => adt.variant_of_res(res),
+            ty::Adt(adt, _) => {
+                self.check_def_id(adt.did());
+                adt.variant_of_res(res)
+            }
             _ => span_bug!(lhs.span, "non-ADT in struct pattern"),
         };
         for pat in pats {
@@ -297,7 +300,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         dotdot: hir::DotDotPos,
     ) {
         let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
-            ty::Adt(adt, _) => adt.variant_of_res(res),
+            ty::Adt(adt, _) => {
+                self.check_def_id(adt.did());
+                adt.variant_of_res(res)
+            }
             _ => {
                 self.tcx.dcx().span_delayed_bug(lhs.span, "non-ADT in tuple struct pattern");
                 return;
@@ -402,31 +408,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 return false;
             }
 
-            // don't ignore impls for Enums and pub Structs whose methods don't have self receiver,
-            // cause external crate may call such methods to construct values of these types
-            if let Some(local_impl_of) = impl_of.as_local()
-                && let Some(local_def_id) = def_id.as_local()
-                && let Some(fn_sig) =
-                    self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
-                && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
-                && let TyKind::Path(hir::QPath::Resolved(_, path)) =
-                    self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind
-                && let Res::Def(def_kind, did) = path.res
-            {
-                match def_kind {
-                    // for example, #[derive(Default)] pub struct T(i32);
-                    // external crate can call T::default() to construct T,
-                    // so that don't ignore impl Default for pub Enum and Structs
-                    DefKind::Struct | DefKind::Union if self.tcx.visibility(did).is_public() => {
-                        return false;
-                    }
-                    // don't ignore impl Default for Enums,
-                    // cause we don't know which variant is constructed
-                    DefKind::Enum => return false,
-                    _ => (),
-                };
-            }
-
             if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
                 && self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
             {
@@ -690,6 +671,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
                 self.handle_field_pattern_match(pat, res, fields);
             }
             PatKind::Path(ref qpath) => {
+                if let ty::Adt(adt, _) = self.typeck_results().node_type(pat.hir_id).kind() {
+                    self.check_def_id(adt.did());
+                }
                 let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
                 self.handle_res(res);
             }
@@ -845,7 +829,7 @@ fn check_item<'tcx>(
                 // mark the method live if the self_ty is public,
                 // or the method is public and may construct self
                 if tcx.visibility(local_def_id).is_public()
-                    && (ty_and_all_fields_are_public || may_construct_self)
+                    && (ty_and_all_fields_are_public || (ty_is_public && may_construct_self))
                 {
                     // if the impl item is public,
                     // and the ty may be constructed or can be constructed in foreign crates,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7da9211bcbf..af56f4e5141 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1513,6 +1513,7 @@ symbols! {
         recursion_limit,
         reexport_test_harness_main,
         ref_pat_eat_one_layer_2024,
+        ref_pat_eat_one_layer_2024_structural,
         ref_pat_everywhere,
         ref_unwind_safe_trait,
         reference,
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 643d5f80480..f98744e906f 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -1,21 +1,18 @@
 use std::ops::Deref;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::DefId;
 use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
 use rustc_infer::infer::canonical::{
     Canonical, CanonicalExt as _, CanonicalVarInfo, CanonicalVarValues,
 };
-use rustc_infer::infer::{
-    BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt,
-};
+use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::solve::Goal;
 use rustc_infer::traits::util::supertraits;
 use rustc_infer::traits::{ObligationCause, Reveal};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
 use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
-use rustc_type_ir::relate::Relate;
 use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode};
 
 use crate::traits::coherence::trait_ref_is_knowable;
@@ -48,13 +45,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
 
     type Span = Span;
 
-    fn solver_mode(&self) -> ty::solve::SolverMode {
-        match self.intercrate {
-            true => SolverMode::Coherence,
-            false => SolverMode::Normal,
-        }
-    }
-
     fn build_with_canonical<V>(
         interner: TyCtxt<'tcx>,
         solver_mode: SolverMode,
@@ -74,104 +64,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         (SolverDelegate(infcx), value, vars)
     }
 
-    fn universe(&self) -> ty::UniverseIndex {
-        self.0.universe()
-    }
-
-    fn create_next_universe(&self) -> ty::UniverseIndex {
-        self.0.create_next_universe()
-    }
-
-    fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
-        // FIXME(BoxyUwU): this is kind of jank and means that printing unresolved
-        // ty infers will give you the universe of the var it resolved to not the universe
-        // it actually had. It also means that if you have a `?0.1` and infer it to `u8` then
-        // try to print out `?0.1` it will just print `?0`.
-        match self.0.probe_ty_var(vid) {
-            Err(universe) => Some(universe),
-            Ok(_) => None,
-        }
-    }
-
-    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
-        match self.0.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
-            Err(universe) => Some(universe),
-            Ok(_) => None,
-        }
-    }
-
-    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> {
-        // Same issue as with `universe_of_ty`
-        match self.0.probe_const_var(ct) {
-            Err(universe) => Some(universe),
-            Ok(_) => None,
-        }
-    }
-
-    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid {
-        self.0.root_var(var)
-    }
-
-    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
-        self.0.root_const_var(var)
-    }
-
-    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> {
-        match self.0.probe_ty_var(vid) {
-            Ok(ty) => ty,
-            Err(_) => Ty::new_var(self.0.tcx, self.0.root_var(vid)),
-        }
-    }
-
-    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
-        self.0.opportunistic_resolve_int_var(vid)
-    }
-
-    fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
-        self.0.opportunistic_resolve_float_var(vid)
-    }
-
-    fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> {
-        match self.0.probe_const_var(vid) {
-            Ok(ct) => ct,
-            Err(_) => ty::Const::new_var(self.0.tcx, self.0.root_const_var(vid)),
-        }
-    }
-
-    fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> {
-        match self.0.probe_effect_var(vid) {
-            Some(ct) => ct,
-            None => ty::Const::new_infer(
-                self.0.tcx,
-                ty::InferConst::EffectVar(self.0.root_effect_var(vid)),
-            ),
-        }
-    }
-
-    fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
-        self.0
-            .inner
-            .borrow_mut()
-            .unwrap_region_constraints()
-            .opportunistic_resolve_var(self.0.tcx, vid)
-    }
-
-    fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
-        self.0.defining_opaque_types()
-    }
-
-    fn next_ty_infer(&self) -> Ty<'tcx> {
-        self.0.next_ty_var(DUMMY_SP)
-    }
-
-    fn next_const_infer(&self) -> ty::Const<'tcx> {
-        self.0.next_const_var(DUMMY_SP)
-    }
-
-    fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
-        self.0.fresh_args_for_item(DUMMY_SP, def_id)
-    }
-
     fn fresh_var_for_kind_with_span(
         &self,
         arg: ty::GenericArg<'tcx>,
@@ -186,57 +78,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         }
     }
 
-    fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
-        &self,
-        value: ty::Binder<'tcx, T>,
-    ) -> T {
-        self.0.instantiate_binder_with_fresh_vars(
-            DUMMY_SP,
-            BoundRegionConversionTime::HigherRankedType,
-            value,
-        )
-    }
-
-    fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
-        &self,
-        value: ty::Binder<'tcx, T>,
-        f: impl FnOnce(T) -> U,
-    ) -> U {
-        self.0.enter_forall(value, f)
-    }
-
-    fn relate<T: Relate<TyCtxt<'tcx>>>(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        lhs: T,
-        variance: ty::Variance,
-        rhs: T,
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
-        self.0.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
-    }
-
-    fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        lhs: T,
-        rhs: T,
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
-        self.0
-            .at(&ObligationCause::dummy(), param_env)
-            .eq_structurally_relating_aliases_no_trace(lhs, rhs)
-    }
-
-    fn resolve_vars_if_possible<T>(&self, value: T) -> T
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.0.resolve_vars_if_possible(value)
-    }
-
-    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
-        self.0.probe(|_| probe())
-    }
-
     fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution> {
         self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution)
     }
@@ -265,14 +106,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         }
     }
 
-    fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) {
-        self.0.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup)
-    }
-
-    fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) {
-        self.0.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy());
-    }
-
     fn well_formed_goals(
         &self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index f1611bd049d..5b2c8fb1950 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -805,10 +805,11 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
                         .unwrap()
                         .contains(&data.trait_ref(self.tcx).def_id);
 
+                    // only walk contained types if it's not a super trait
                     if is_supertrait_of_current_trait {
-                        ControlFlow::Continue(()) // do not walk contained types, do not report error, do collect $200
+                        ControlFlow::Continue(())
                     } else {
-                        t.super_visit_with(self) // DO walk contained types, POSSIBLY reporting an error
+                        t.super_visit_with(self) // POSSIBLY reporting an error
                     }
                 }
                 _ => t.super_visit_with(self), // walk contained types, if any
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index b38841db923..8525215a3bc 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -3,7 +3,6 @@ use crate::traits::wf;
 use crate::traits::ObligationCtxt;
 
 use rustc_infer::infer::canonical::Canonical;
-use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::query::OutlivesBound;
 use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
@@ -12,6 +11,7 @@ use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::DUMMY_SP;
+use rustc_type_ir::outlives::{push_outlives_components, Component};
 use smallvec::{smallvec, SmallVec};
 
 #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable)]
@@ -284,7 +284,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
 /// those relationships.
 fn implied_bounds_from_components<'tcx>(
     sub_region: ty::Region<'tcx>,
-    sup_components: SmallVec<[Component<'tcx>; 4]>,
+    sup_components: SmallVec<[Component<TyCtxt<'tcx>>; 4]>,
 ) -> Vec<OutlivesBound<'tcx>> {
     sup_components
         .into_iter()
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index e3952679f96..f071dc6c784 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -640,8 +640,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
-    type Result = ();
-
     fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
         debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind());
 
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
new file mode 100644
index 00000000000..2c80ee0a73d
--- /dev/null
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -0,0 +1,93 @@
+use crate::fold::TypeFoldable;
+use crate::relate::Relate;
+use crate::solve::{Goal, NoSolution, SolverMode};
+use crate::{self as ty, Interner};
+
+pub trait InferCtxtLike {
+    type Interner: Interner;
+    fn cx(&self) -> Self::Interner;
+
+    fn solver_mode(&self) -> SolverMode;
+
+    fn universe(&self) -> ty::UniverseIndex;
+    fn create_next_universe(&self) -> ty::UniverseIndex;
+
+    fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
+    fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
+    fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
+
+    fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
+    fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
+
+    fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
+    fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
+    fn opportunistic_resolve_float_var(
+        &self,
+        vid: ty::FloatVid,
+    ) -> <Self::Interner as Interner>::Ty;
+    fn opportunistic_resolve_ct_var(
+        &self,
+        vid: ty::ConstVid,
+    ) -> <Self::Interner as Interner>::Const;
+    fn opportunistic_resolve_effect_var(
+        &self,
+        vid: ty::EffectVid,
+    ) -> <Self::Interner as Interner>::Const;
+    fn opportunistic_resolve_lt_var(
+        &self,
+        vid: ty::RegionVid,
+    ) -> <Self::Interner as Interner>::Region;
+
+    fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes;
+
+    fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
+    fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
+    fn fresh_args_for_item(
+        &self,
+        def_id: <Self::Interner as Interner>::DefId,
+    ) -> <Self::Interner as Interner>::GenericArgs;
+
+    fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
+        &self,
+        value: ty::Binder<Self::Interner, T>,
+    ) -> T;
+
+    fn enter_forall<T: TypeFoldable<Self::Interner> + Copy, U>(
+        &self,
+        value: ty::Binder<Self::Interner, T>,
+        f: impl FnOnce(T) -> U,
+    ) -> U;
+
+    fn relate<T: Relate<Self::Interner>>(
+        &self,
+        param_env: <Self::Interner as Interner>::ParamEnv,
+        lhs: T,
+        variance: ty::Variance,
+        rhs: T,
+    ) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>;
+
+    fn eq_structurally_relating_aliases<T: Relate<Self::Interner>>(
+        &self,
+        param_env: <Self::Interner as Interner>::ParamEnv,
+        lhs: T,
+        rhs: T,
+    ) -> Result<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>, NoSolution>;
+
+    fn resolve_vars_if_possible<T>(&self, value: T) -> T
+    where
+        T: TypeFoldable<Self::Interner>;
+
+    fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
+
+    fn sub_regions(
+        &self,
+        sub: <Self::Interner as Interner>::Region,
+        sup: <Self::Interner as Interner>::Region,
+    );
+
+    fn register_ty_outlives(
+        &self,
+        ty: <Self::Interner as Interner>::Ty,
+        r: <Self::Interner as Interner>::Region,
+    );
+}
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index ffe16964ae5..68c2575258d 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -232,6 +232,10 @@ pub trait Region<I: Interner<Region = Self>>:
     fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
 
     fn new_static(interner: I) -> Self;
+
+    fn is_bound(self) -> bool {
+        matches!(self.kind(), ty::ReBound(..))
+    }
 }
 
 pub trait Const<I: Interner<Const = Self>>:
@@ -272,6 +276,10 @@ pub trait Const<I: Interner<Const = Self>>:
     }
 }
 
+pub trait ExprConst<I: Interner<ExprConst = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
+    fn args(self) -> I::GenericArgs;
+}
+
 pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
     fn count(&self) -> usize;
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index db97bdca382..6e013768c3e 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -32,6 +32,7 @@ pub trait Interner:
 {
     type DefId: DefId<Self>;
     type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
+    type Span: Copy + Debug + Hash + Eq;
 
     type GenericArgs: GenericArgs<Self>;
     type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>;
@@ -109,7 +110,7 @@ pub trait Interner:
     type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
     type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
     type ValueConst: Copy + Debug + Hash + Eq;
-    type ExprConst: Copy + Debug + Hash + Eq + Relate<Self>;
+    type ExprConst: ExprConst<Self>;
 
     // Kinds of regions
     type Region: Region<Self>;
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index fedc8959cf7..2a909b06baf 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -27,6 +27,7 @@ pub mod inherent;
 pub mod ir_print;
 pub mod lang_items;
 pub mod lift;
+pub mod outlives;
 pub mod relate;
 pub mod solve;
 
@@ -39,6 +40,7 @@ mod const_kind;
 mod effects;
 mod flags;
 mod generic_arg;
+mod infer_ctxt;
 mod interner;
 mod opaque_ty;
 mod predicate;
@@ -56,6 +58,7 @@ pub use const_kind::*;
 pub use effects::*;
 pub use flags::*;
 pub use generic_arg::*;
+pub use infer_ctxt::*;
 pub use interner::*;
 pub use opaque_ty::*;
 pub use predicate::*;
diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs
new file mode 100644
index 00000000000..10b6f3355d9
--- /dev/null
+++ b/compiler/rustc_type_ir/src/outlives.rs
@@ -0,0 +1,228 @@
+//! The outlives relation `T: 'a` or `'a: 'b`. This code frequently
+//! refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
+//! RFC for reference.
+
+use smallvec::{smallvec, SmallVec};
+
+use crate::data_structures::SsoHashSet;
+use crate::inherent::*;
+use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor};
+use crate::{self as ty, Interner};
+
+#[derive(derivative::Derivative)]
+#[derivative(Debug(bound = ""))]
+pub enum Component<I: Interner> {
+    Region(I::Region),
+    Param(I::ParamTy),
+    Placeholder(I::PlaceholderTy),
+    UnresolvedInferenceVariable(ty::InferTy),
+
+    // Projections like `T::Foo` are tricky because a constraint like
+    // `T::Foo: 'a` can be satisfied in so many ways. There may be a
+    // where-clause that says `T::Foo: 'a`, or the defining trait may
+    // include a bound like `type Foo: 'static`, or -- in the most
+    // conservative way -- we can prove that `T: 'a` (more generally,
+    // that all components in the projection outlive `'a`). This code
+    // is not in a position to judge which is the best technique, so
+    // we just product the projection as a component and leave it to
+    // the consumer to decide (but see `EscapingProjection` below).
+    Alias(ty::AliasTy<I>),
+
+    // In the case where a projection has escaping regions -- meaning
+    // regions bound within the type itself -- we always use
+    // the most conservative rule, which requires that all components
+    // outlive the bound. So for example if we had a type like this:
+    //
+    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >
+    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~
+    //
+    // then the inner projection (underlined) has an escaping region
+    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`
+    // outlives `'b: 'c`, and we don't consider whether the trait
+    // declares that `Foo: 'static` etc. Therefore, we just return the
+    // free components of such a projection (in this case, `'b`).
+    //
+    // However, in the future, we may want to get smarter, and
+    // actually return a "higher-ranked projection" here. Therefore,
+    // we mark that these components are part of an escaping
+    // projection, so that implied bounds code can avoid relying on
+    // them. This gives us room to improve the regionck reasoning in
+    // the future without breaking backwards compat.
+    EscapingAlias(Vec<Component<I>>),
+}
+
+/// Push onto `out` all the things that must outlive `'a` for the condition
+/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
+pub fn push_outlives_components<I: Interner>(
+    tcx: I,
+    ty: I::Ty,
+    out: &mut SmallVec<[Component<I>; 4]>,
+) {
+    ty.visit_with(&mut OutlivesCollector { tcx, out, visited: Default::default() });
+}
+
+struct OutlivesCollector<'a, I: Interner> {
+    tcx: I,
+    out: &'a mut SmallVec<[Component<I>; 4]>,
+    visited: SsoHashSet<I::Ty>,
+}
+
+impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
+    fn visit_ty(&mut self, ty: I::Ty) -> Self::Result {
+        if !self.visited.insert(ty) {
+            return;
+        }
+        // Descend through the types, looking for the various "base"
+        // components and collecting them into `out`. This is not written
+        // with `collect()` because of the need to sometimes skip subtrees
+        // in the `subtys` iterator (e.g., when encountering a
+        // projection).
+        match ty.kind() {
+            ty::FnDef(_, args) => {
+                // HACK(eddyb) ignore lifetimes found shallowly in `args`.
+                // This is inconsistent with `ty::Adt` (including all args)
+                // and with `ty::Closure` (ignoring all args other than
+                // upvars, of which a `ty::FnDef` doesn't have any), but
+                // consistent with previous (accidental) behavior.
+                // See https://github.com/rust-lang/rust/issues/70917
+                // for further background and discussion.
+                for child in args.iter() {
+                    match child.kind() {
+                        ty::GenericArgKind::Lifetime(_) => {}
+                        ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_) => {
+                            child.visit_with(self);
+                        }
+                    }
+                }
+            }
+
+            ty::Closure(_, args) => {
+                args.as_closure().tupled_upvars_ty().visit_with(self);
+            }
+
+            ty::CoroutineClosure(_, args) => {
+                args.as_coroutine_closure().tupled_upvars_ty().visit_with(self);
+            }
+
+            ty::Coroutine(_, args) => {
+                args.as_coroutine().tupled_upvars_ty().visit_with(self);
+
+                // We ignore regions in the coroutine interior as we don't
+                // want these to affect region inference
+            }
+
+            // All regions are bound inside a witness, and we don't emit
+            // higher-ranked outlives components currently.
+            ty::CoroutineWitness(..) => {}
+
+            // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
+            // is implied by the environment is done in regionck.
+            ty::Param(p) => {
+                self.out.push(Component::Param(p));
+            }
+
+            ty::Placeholder(p) => {
+                self.out.push(Component::Placeholder(p));
+            }
+
+            // For projections, we prefer to generate an obligation like
+            // `<P0 as Trait<P1...Pn>>::Foo: 'a`, because this gives the
+            // regionck more ways to prove that it holds. However,
+            // regionck is not (at least currently) prepared to deal with
+            // higher-ranked regions that may appear in the
+            // trait-ref. Therefore, if we see any higher-ranked regions,
+            // we simply fallback to the most restrictive rule, which
+            // requires that `Pi: 'a` for all `i`.
+            ty::Alias(_, alias_ty) => {
+                if !alias_ty.has_escaping_bound_vars() {
+                    // best case: no escaping regions, so push the
+                    // projection and skip the subtree (thus generating no
+                    // constraints for Pi). This defers the choice between
+                    // the rules OutlivesProjectionEnv,
+                    // OutlivesProjectionTraitDef, and
+                    // OutlivesProjectionComponents to regionck.
+                    self.out.push(Component::Alias(alias_ty));
+                } else {
+                    // fallback case: hard code
+                    // OutlivesProjectionComponents. Continue walking
+                    // through and constrain Pi.
+                    let mut subcomponents = smallvec![];
+                    compute_alias_components_recursive(self.tcx, ty, &mut subcomponents);
+                    self.out.push(Component::EscapingAlias(subcomponents.into_iter().collect()));
+                }
+            }
+
+            // We assume that inference variables are fully resolved.
+            // So, if we encounter an inference variable, just record
+            // the unresolved variable as a component.
+            ty::Infer(infer_ty) => {
+                self.out.push(Component::UnresolvedInferenceVariable(infer_ty));
+            }
+
+            // Most types do not introduce any region binders, nor
+            // involve any other subtle cases, and so the WF relation
+            // simply constraints any regions referenced directly by
+            // the type and then visits the types that are lexically
+            // contained within.
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Str
+            | ty::Never
+            | ty::Error(_) => {
+                // Trivial
+            }
+
+            ty::Bound(_, _) => {
+                // FIXME: Bound vars matter here!
+            }
+
+            ty::Adt(_, _)
+            | ty::Foreign(_)
+            | ty::Array(_, _)
+            | ty::Pat(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_, _)
+            | ty::Ref(_, _, _)
+            | ty::FnPtr(_)
+            | ty::Dynamic(_, _, _)
+            | ty::Tuple(_) => {
+                ty.super_visit_with(self);
+            }
+        }
+    }
+
+    fn visit_region(&mut self, lt: I::Region) -> Self::Result {
+        if !lt.is_bound() {
+            self.out.push(Component::Region(lt));
+        }
+    }
+}
+
+/// Collect [Component]s for *all* the args of `parent`.
+///
+/// This should not be used to get the components of `parent` itself.
+/// Use [push_outlives_components] instead.
+pub fn compute_alias_components_recursive<I: Interner>(
+    tcx: I,
+    alias_ty: I::Ty,
+    out: &mut SmallVec<[Component<I>; 4]>,
+) {
+    let ty::Alias(kind, alias_ty) = alias_ty.kind() else {
+        unreachable!("can only call `compute_alias_components_recursive` on an alias type")
+    };
+
+    let opt_variances =
+        if kind == ty::Opaque { Some(tcx.variances_of(alias_ty.def_id)) } else { None };
+
+    let mut visitor = OutlivesCollector { tcx, out, visited: Default::default() };
+
+    for (index, child) in alias_ty.args.iter().enumerate() {
+        if opt_variances.and_then(|variances| variances.get(index)) == Some(ty::Bivariant) {
+            continue;
+        }
+        child.visit_with(&mut visitor);
+    }
+}
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 5cacedcb241..4524b352ec8 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -103,7 +103,6 @@ use crate::ascii::Char as AsciiChar;
 /// ```
 #[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)]
 pub trait Default: Sized {
     /// Returns the "default value" for a type.
     ///
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index d0e188dfcd1..25ab5b2db96 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -517,7 +517,10 @@ impl Display for Arguments<'_> {
 ///
 /// let origin = Point { x: 0, y: 0 };
 ///
-/// assert_eq!(format!("The origin is: {origin:?}"), "The origin is: Point { x: 0, y: 0 }");
+/// assert_eq!(
+///     format!("The origin is: {origin:?}"),
+///     "The origin is: Point { x: 0, y: 0 }",
+/// );
 /// ```
 ///
 /// Manually implementing:
@@ -541,7 +544,10 @@ impl Display for Arguments<'_> {
 ///
 /// let origin = Point { x: 0, y: 0 };
 ///
-/// assert_eq!(format!("The origin is: {origin:?}"), "The origin is: Point { x: 0, y: 0 }");
+/// assert_eq!(
+///     format!("The origin is: {origin:?}"),
+///     "The origin is: Point { x: 0, y: 0 }",
+/// );
 /// ```
 ///
 /// There are a number of helper methods on the [`Formatter`] struct to help you with manual
@@ -582,11 +588,11 @@ impl Display for Arguments<'_> {
 ///
 /// let origin = Point { x: 0, y: 0 };
 ///
-/// assert_eq!(format!("The origin is: {origin:#?}"),
-/// "The origin is: Point {
+/// let expected = "The origin is: Point {
 ///     x: 0,
 ///     y: 0,
-/// }");
+/// }";
+/// assert_eq!(format!("The origin is: {origin:#?}"), expected);
 /// ```
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -738,8 +744,10 @@ pub trait Display {
     ///     }
     /// }
     ///
-    /// assert_eq!("(1.987, 2.983)",
-    ///            format!("{}", Position { longitude: 1.987, latitude: 2.983, }));
+    /// assert_eq!(
+    ///     "(1.987, 2.983)",
+    ///     format!("{}", Position { longitude: 1.987, latitude: 2.983, }),
+    /// );
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, f: &mut Formatter<'_>) -> Result;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index c5a1fca667b..0f82f01e57a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -395,6 +395,8 @@ pub mod panicking;
 #[unstable(feature = "core_pattern_types", issue = "none")]
 pub mod pat;
 pub mod pin;
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub mod range;
 pub mod result;
 pub mod sync;
 
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 5537d26669a..68cf8203433 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -390,37 +390,26 @@ impl<T: ?Sized> *const T {
         if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
     }
 
-    /// Calculates the offset from a pointer.
+    /// Adds an offset to a pointer.
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
-    ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_offset`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
@@ -611,8 +600,7 @@ impl<T: ?Sized> *const T {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
     /// * `self` and `origin` must either
     ///
@@ -623,26 +611,10 @@ impl<T: ?Sized> *const T {
     /// * The distance between the pointers, in bytes, must be an exact multiple
     ///   of the size of `T`.
     ///
-    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
-    ///
-    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
-    ///
-    /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the
-    /// address space, so two pointers within some value of any Rust type `T` will always satisfy
-    /// the last two conditions. The standard library also generally ensures that allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they
-    /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())`
-    /// always satisfies the last two conditions.
-    ///
-    /// Most platforms fundamentally can't even construct such a large allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
-    /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
-    /// such large allocations either.)
+    /// As a consequence, the absolute distance between the pointers, in bytes, computed on
+    /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is
+    /// implied by the in-bounds requirement, and the fact that no allocated object can be larger
+    /// than `isize::MAX` bytes.
     ///
     /// The requirement for pointers to be derived from the same allocated object is primarily
     /// needed for `const`-compatibility: the distance between pointers into *different* allocated
@@ -879,37 +851,26 @@ impl<T: ?Sized> *const T {
         }
     }
 
-    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
+    /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a `usize`.
-    ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_add`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
@@ -963,7 +924,7 @@ impl<T: ?Sized> *const T {
         unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
     }
 
-    /// Calculates the offset from a pointer (convenience for
+    /// Subtracts an offset from a pointer (convenience for
     /// `.offset((count as isize).wrapping_neg())`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -971,30 +932,19 @@ impl<T: ?Sized> *const T {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
-    ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
-    ///
-    /// * The computed offset cannot exceed `isize::MAX` **bytes**.
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a usize.
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_sub`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 30d5b2cfc5a..0dc910db5b9 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -404,37 +404,26 @@ impl<T: ?Sized> *mut T {
         if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
     }
 
-    /// Calculates the offset from a pointer.
+    /// Adds an offset to a pointer.
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
-    ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_offset`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
@@ -836,8 +825,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
     /// * `self` and `origin` must either
     ///
@@ -848,26 +836,10 @@ impl<T: ?Sized> *mut T {
     /// * The distance between the pointers, in bytes, must be an exact multiple
     ///   of the size of `T`.
     ///
-    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
-    ///
-    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
-    ///
-    /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the
-    /// address space, so two pointers within some value of any Rust type `T` will always satisfy
-    /// the last two conditions. The standard library also generally ensures that allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they
-    /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())`
-    /// always satisfies the last two conditions.
-    ///
-    /// Most platforms fundamentally can't even construct such a large allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
-    /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
-    /// such large allocations either.)
+    /// As a consequence, the absolute distance between the pointers, in bytes, computed on
+    /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is
+    /// implied by the in-bounds requirement, and the fact that no allocated object can be larger
+    /// than `isize::MAX` bytes.
     ///
     /// The requirement for pointers to be derived from the same allocated object is primarily
     /// needed for `const`-compatibility: the distance between pointers into *different* allocated
@@ -1020,37 +992,26 @@ impl<T: ?Sized> *mut T {
         unsafe { (self as *const T).sub_ptr(origin) }
     }
 
-    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
+    /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a `usize`.
-    ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_add`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
@@ -1104,7 +1065,7 @@ impl<T: ?Sized> *mut T {
         unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
     }
 
-    /// Calculates the offset from a pointer (convenience for
+    /// Subtracts an offset from a pointer (convenience for
     /// `.offset((count as isize).wrapping_neg())`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -1112,30 +1073,19 @@ impl<T: ?Sized> *mut T {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
-    ///
-    /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
-    ///   pointer must be either in bounds or at the end of the same [allocated object].
-    ///   (If it is zero, then the function is always well-defined.)
-    ///
-    /// * The computed offset cannot exceed `isize::MAX` **bytes**.
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a usize.
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// Consider using [`wrapping_sub`] instead if these constraints are
     /// difficult to satisfy. The only advantage of this method is that it
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 0504a0fc32f..75a99e14fda 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -476,36 +476,26 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { NonNull { pointer: self.as_ptr() as *mut U } }
     }
 
-    /// Calculates the offset from a pointer.
+    /// Adds an offset to a pointer.
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same [allocated object].
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
-    ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// [allocated object]: crate::ptr#allocated-object
     ///
@@ -562,36 +552,26 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { NonNull { pointer: self.pointer.byte_offset(count) } }
     }
 
-    /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
+    /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
     /// offset of `3 * size_of::<T>()` bytes.
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
-    ///
-    /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same [allocated object].
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a `usize`.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len())` is always safe.
-    ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// [allocated object]: crate::ptr#allocated-object
     ///
@@ -649,7 +629,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { NonNull { pointer: self.pointer.byte_add(count) } }
     }
 
-    /// Calculates the offset from a pointer (convenience for
+    /// Subtracts an offset from a pointer (convenience for
     /// `.offset((count as isize).wrapping_neg())`).
     ///
     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -657,29 +637,19 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
-    ///
-    /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of the same [allocated object].
-    ///
-    /// * The computed offset cannot exceed `isize::MAX` **bytes**.
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * The offset being in bounds cannot rely on "wrapping around" the address
-    ///   space. That is, the infinite-precision sum must fit in a usize.
+    /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
     ///
-    /// The compiler and standard library generally tries to ensure allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec`
-    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
-    /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
+    /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
+    ///   [allocated object], and the entire memory range between `self` and the result must be in
+    ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
+    ///   of the address space.
     ///
-    /// Most platforms fundamentally can't even construct such an allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
+    /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+    /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
+    /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
+    /// safe.
     ///
     /// [allocated object]: crate::ptr#allocated-object
     ///
@@ -761,38 +731,21 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// # Safety
     ///
-    /// If any of the following conditions are violated, the result is Undefined
-    /// Behavior:
+    /// If any of the following conditions are violated, the result is Undefined Behavior:
     ///
-    /// * Both `self` and `origin` must be either in bounds or one
-    ///   byte past the end of the same [allocated object].
+    /// * `self` and `origin` must either
     ///
-    /// * Both pointers must be *derived from* a pointer to the same object.
-    ///   (See below for an example.)
+    ///   * both be *derived from* a pointer to the same [allocated object], and the memory range between
+    ///     the two pointers must be either empty or in bounds of that object. (See below for an example.)
+    ///   * or both be derived from an integer literal/constant, and point to the same address.
     ///
     /// * The distance between the pointers, in bytes, must be an exact multiple
     ///   of the size of `T`.
     ///
-    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
-    ///
-    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
-    ///
-    /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the
-    /// address space, so two pointers within some value of any Rust type `T` will always satisfy
-    /// the last two conditions. The standard library also generally ensures that allocations
-    /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they
-    /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())`
-    /// always satisfies the last two conditions.
-    ///
-    /// Most platforms fundamentally can't even construct such a large allocation.
-    /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
-    /// However, some 32-bit and 16-bit platforms may successfully serve a request for
-    /// more than `isize::MAX` bytes with things like Physical Address
-    /// Extension. As such, memory acquired directly from allocators or memory
-    /// mapped files *may* be too large to handle with this function.
-    /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
-    /// such large allocations either.)
+    /// As a consequence, the absolute distance between the pointers, in bytes, computed on
+    /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is
+    /// implied by the in-bounds requirement, and the fact that no allocated object can be larger
+    /// than `isize::MAX` bytes.
     ///
     /// The requirement for pointers to be derived from the same allocated object is primarily
     /// needed for `const`-compatibility: the distance between pointers into *different* allocated
diff --git a/library/core/src/range.rs b/library/core/src/range.rs
new file mode 100644
index 00000000000..bfbbf123b1c
--- /dev/null
+++ b/library/core/src/range.rs
@@ -0,0 +1,494 @@
+//! # Experimental replacement range types
+//!
+//! The types within this module are meant to replace the existing
+//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition.
+//!
+//! ```
+//! #![feature(new_range_api)]
+//! use core::range::{Range, RangeFrom, RangeInclusive};
+//!
+//! let arr = [0, 1, 2, 3, 4];
+//! assert_eq!(arr[                      ..   ], [0, 1, 2, 3, 4]);
+//! assert_eq!(arr[                      .. 3 ], [0, 1, 2      ]);
+//! assert_eq!(arr[                      ..=3 ], [0, 1, 2, 3   ]);
+//! assert_eq!(arr[     RangeFrom::from(1..  )], [   1, 2, 3, 4]);
+//! assert_eq!(arr[         Range::from(1..3 )], [   1, 2      ]);
+//! assert_eq!(arr[RangeInclusive::from(1..=3)], [   1, 2, 3   ]);
+//! ```
+
+use crate::fmt;
+use crate::hash::Hash;
+
+mod iter;
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub mod legacy;
+
+#[doc(inline)]
+pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive};
+
+use Bound::{Excluded, Included, Unbounded};
+
+#[doc(inline)]
+pub use crate::iter::Step;
+
+#[doc(inline)]
+pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive};
+
+/// A (half-open) range bounded inclusively below and exclusively above
+/// (`start..end` in a future edition).
+///
+/// The range `start..end` contains all values with `start <= x < end`.
+/// It is empty if `start >= end`.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::Range;
+///
+/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 });
+/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
+/// ```
+#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct Range<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+    /// The upper bound of the range (exclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub end: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: Step> Range<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// let mut i = Range::from(3..9).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRange<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> Range<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3..5).contains(&2));
+    /// assert!( Range::from(3..5).contains(&3));
+    /// assert!( Range::from(3..5).contains(&4));
+    /// assert!(!Range::from(3..5).contains(&5));
+    ///
+    /// assert!(!Range::from(3..3).contains(&3));
+    /// assert!(!Range::from(3..2).contains(&3));
+    ///
+    /// assert!( Range::from(0.0..1.0).contains(&0.5));
+    /// assert!(!Range::from(0.0..1.0).contains(&f32::NAN));
+    /// assert!(!Range::from(0.0..f32::NAN).contains(&0.5));
+    /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3..5).is_empty());
+    /// assert!( Range::from(3..3).is_empty());
+    /// assert!( Range::from(3..2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::Range;
+    ///
+    /// assert!(!Range::from(3.0..5.0).is_empty());
+    /// assert!( Range::from(3.0..f32::NAN).is_empty());
+    /// assert!( Range::from(f32::NAN..5.0).is_empty());
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn is_empty(&self) -> bool {
+        !(self.start < self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for Range<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for Range<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<Range<T>> for legacy::Range<T> {
+    #[inline]
+    fn from(value: Range<T>) -> Self {
+        Self { start: value.start, end: value.end }
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::Range<T>> for Range<T> {
+    #[inline]
+    fn from(value: legacy::Range<T>) -> Self {
+        Self { start: value.start, end: value.end }
+    }
+}
+
+/// A range bounded inclusively below and above (`start..=end`).
+///
+/// The `RangeInclusive` `start..=end` contains all values with `x >= start`
+/// and `x <= end`. It is empty unless `start <= end`.
+///
+/// # Examples
+///
+/// The `start..=end` syntax is a `RangeInclusive`:
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::RangeInclusive;
+///
+/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 });
+/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum());
+/// ```
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct RangeInclusive<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+    /// The upper bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub end: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..=")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3..=5).contains(&2));
+    /// assert!( RangeInclusive::from(3..=5).contains(&3));
+    /// assert!( RangeInclusive::from(3..=5).contains(&4));
+    /// assert!( RangeInclusive::from(3..=5).contains(&5));
+    /// assert!(!RangeInclusive::from(3..=5).contains(&6));
+    ///
+    /// assert!( RangeInclusive::from(3..=3).contains(&3));
+    /// assert!(!RangeInclusive::from(3..=2).contains(&3));
+    ///
+    /// assert!( RangeInclusive::from(0.0..=1.0).contains(&1.0));
+    /// assert!(!RangeInclusive::from(0.0..=1.0).contains(&f32::NAN));
+    /// assert!(!RangeInclusive::from(0.0..=f32::NAN).contains(&0.0));
+    /// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3..=5).is_empty());
+    /// assert!(!RangeInclusive::from(3..=3).is_empty());
+    /// assert!( RangeInclusive::from(3..=2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// assert!(!RangeInclusive::from(3.0..=5.0).is_empty());
+    /// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty());
+    /// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty());
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        !(self.start <= self.end)
+    }
+}
+
+impl<Idx: Step> RangeInclusive<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeInclusive;
+    ///
+    /// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRangeInclusive<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl RangeInclusive<usize> {
+    /// Converts to an exclusive `Range` for `SliceIndex` implementations.
+    /// The caller is responsible for dealing with `end == usize::MAX`.
+    #[inline]
+    pub(crate) const fn into_slice_range(self) -> Range<usize> {
+        Range { start: self.start, end: self.end + 1 }
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeInclusive<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeInclusive<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
+    #[inline]
+    fn from(value: RangeInclusive<T>) -> Self {
+        Self::new(value.start, value.end)
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
+    #[inline]
+    fn from(value: legacy::RangeInclusive<T>) -> Self {
+        assert!(
+            !value.exhausted,
+            "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)"
+        );
+
+        let (start, end) = value.into_inner();
+        RangeInclusive { start, end }
+    }
+}
+
+/// A range only bounded inclusively below (`start..`).
+///
+/// The `RangeFrom` `start..` contains all values with `x >= start`.
+///
+/// *Note*: Overflow in the [`Iterator`] implementation (when the contained
+/// data type reaches its numerical limit) is allowed to panic, wrap, or
+/// saturate. This behavior is defined by the implementation of the [`Step`]
+/// trait. For primitive integers, this follows the normal rules, and respects
+/// the overflow checks profile (panic in debug, wrap in release). Note also
+/// that overflow happens earlier than you might assume: the overflow happens
+/// in the call to `next` that yields the maximum value, as the range must be
+/// set to a state to yield the next value.
+///
+/// [`Step`]: crate::iter::Step
+///
+/// # Examples
+///
+/// The `start..` syntax is a `RangeFrom`:
+///
+/// ```
+/// #![feature(new_range_api)]
+/// use core::range::RangeFrom;
+///
+/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 });
+/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
+/// ```
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[unstable(feature = "new_range_api", issue = "125687")]
+pub struct RangeFrom<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub start: Idx,
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        Ok(())
+    }
+}
+
+impl<Idx: Step> RangeFrom<Idx> {
+    /// Create an iterator over the elements within this range.
+    ///
+    /// Shorthand for `.clone().into_iter()`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeFrom;
+    ///
+    /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n);
+    /// assert_eq!(i.next(), Some(9));
+    /// assert_eq!(i.next(), Some(16));
+    /// assert_eq!(i.next(), Some(25));
+    /// ```
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    #[inline]
+    pub fn iter(&self) -> IterRangeFrom<Idx> {
+        self.clone().into_iter()
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_range_api)]
+    /// use core::range::RangeFrom;
+    ///
+    /// assert!(!RangeFrom::from(3..).contains(&2));
+    /// assert!( RangeFrom::from(3..).contains(&3));
+    /// assert!( RangeFrom::from(3..).contains(&1_000_000_000));
+    ///
+    /// assert!( RangeFrom::from(0.0..).contains(&0.5));
+    /// assert!(!RangeFrom::from(0.0..).contains(&f32::NAN));
+    /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5));
+    /// ```
+    #[inline]
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeFrom<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> RangeBounds<T> for RangeFrom<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> {
+    #[inline]
+    fn from(value: RangeFrom<T>) -> Self {
+        Self { start: value.start }
+    }
+}
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<T> From<legacy::RangeFrom<T>> for RangeFrom<T> {
+    #[inline]
+    fn from(value: legacy::RangeFrom<T>) -> Self {
+        Self { start: value.start }
+    }
+}
diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs
new file mode 100644
index 00000000000..2b7db475ffb
--- /dev/null
+++ b/library/core/src/range/iter.rs
@@ -0,0 +1,340 @@
+use crate::num::NonZero;
+use crate::range::{legacy, Range, RangeFrom, RangeInclusive};
+
+use crate::iter::{
+    FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
+};
+
+/// By-value [`Range`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRange<A>(legacy::Range<A>);
+
+impl<A> IterRange<A> {
+    /// Returns the remainder of the range being iterated over.
+    pub fn remainder(self) -> Range<A> {
+        Range { start: self.0.start, end: self.0.end }
+    }
+}
+
+/// Safety: This macro must only be used on types that are `Copy` and result in ranges
+/// which have an exact `size_hint()` where the upper bound must not be `None`.
+macro_rules! unsafe_range_trusted_random_access_impl {
+    ($($t:ty)*) => ($(
+        #[doc(hidden)]
+        #[unstable(feature = "trusted_random_access", issue = "none")]
+        unsafe impl TrustedRandomAccess for IterRange<$t> {}
+
+        #[doc(hidden)]
+        #[unstable(feature = "trusted_random_access", issue = "none")]
+        unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> {
+            const MAY_HAVE_SIDE_EFFECT: bool = false;
+        }
+    )*)
+}
+
+unsafe_range_trusted_random_access_impl! {
+    usize u8 u16
+    isize i8 i16
+}
+
+#[cfg(target_pointer_width = "32")]
+unsafe_range_trusted_random_access_impl! {
+    u32 i32
+}
+
+#[cfg(target_pointer_width = "64")]
+unsafe_range_trusted_random_access_impl! {
+    u32 i32
+    u64 i64
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> Iterator for IterRange<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.0.count()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+
+    #[inline]
+    fn last(self) -> Option<A> {
+        self.0.last()
+    }
+
+    #[inline]
+    fn min(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.min()
+    }
+
+    #[inline]
+    fn max(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.max()
+    }
+
+    #[inline]
+    fn is_sorted(self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_by(n)
+    }
+
+    #[inline]
+    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
+    where
+        Self: TrustedRandomAccessNoCoerce,
+    {
+        // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
+        // that is in bounds.
+        // Additionally Self: TrustedRandomAccess is only implemented for Copy types
+        // which means even repeated reads of the same index would be safe.
+        unsafe { Step::forward_unchecked(self.0.start.clone(), idx) }
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> DoubleEndedIterator for IterRange<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.0.next_back()
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.0.nth_back(n)
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_back_by(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRange<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRange<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for Range<A> {
+    type Item = A;
+    type IntoIter = IterRange<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRange(self.into())
+    }
+}
+
+/// By-value [`RangeInclusive`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRangeInclusive<A>(legacy::RangeInclusive<A>);
+
+impl<A: Step> IterRangeInclusive<A> {
+    /// Returns the remainder of the range being iterated over.
+    ///
+    /// If the iterator is exhausted or empty, returns `None`.
+    pub fn remainder(self) -> Option<RangeInclusive<A>> {
+        if self.0.is_empty() {
+            return None;
+        }
+
+        Some(RangeInclusive { start: self.0.start, end: self.0.end })
+    }
+}
+
+#[unstable(feature = "trusted_random_access", issue = "none")]
+impl<A: Step> Iterator for IterRangeInclusive<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.0.count()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+
+    #[inline]
+    fn last(self) -> Option<A> {
+        self.0.last()
+    }
+
+    #[inline]
+    fn min(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.min()
+    }
+
+    #[inline]
+    fn max(self) -> Option<A>
+    where
+        A: Ord,
+    {
+        self.0.max()
+    }
+
+    #[inline]
+    fn is_sorted(self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_by(n)
+    }
+}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> DoubleEndedIterator for IterRangeInclusive<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.0.next_back()
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<A> {
+        self.0.nth_back(n)
+    }
+
+    #[inline]
+    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
+        self.0.advance_back_by(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRangeInclusive<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRangeInclusive<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for RangeInclusive<A> {
+    type Item = A;
+    type IntoIter = IterRangeInclusive<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRangeInclusive(self.into())
+    }
+}
+
+// These macros generate `ExactSizeIterator` impls for various range types.
+//
+// * `ExactSizeIterator::len` is required to always return an exact `usize`,
+//   so no range can be longer than `usize::MAX`.
+// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`.
+//   For integer types in `RangeInclusive<_>`
+//   this is the case for types *strictly narrower* than `usize`
+//   since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`.
+macro_rules! range_exact_iter_impl {
+    ($($t:ty)*) => ($(
+        #[unstable(feature = "new_range_api", issue = "125687")]
+        impl ExactSizeIterator for IterRange<$t> { }
+    )*)
+}
+
+macro_rules! range_incl_exact_iter_impl {
+    ($($t:ty)*) => ($(
+        #[unstable(feature = "new_range_api", issue = "125687")]
+        impl ExactSizeIterator for IterRangeInclusive<$t> { }
+    )*)
+}
+
+range_exact_iter_impl! {
+    usize u8 u16
+    isize i8 i16
+}
+
+range_incl_exact_iter_impl! {
+    u8
+    i8
+}
+
+/// By-value [`RangeFrom`] iterator.
+#[unstable(feature = "new_range_api", issue = "125687")]
+#[derive(Debug, Clone)]
+pub struct IterRangeFrom<A>(legacy::RangeFrom<A>);
+
+impl<A> IterRangeFrom<A> {
+    /// Returns the remainder of the range being iterated over.
+    pub fn remainder(self) -> RangeFrom<A> {
+        RangeFrom { start: self.0.start }
+    }
+}
+
+#[unstable(feature = "trusted_random_access", issue = "none")]
+impl<A: Step> Iterator for IterRangeFrom<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<A> {
+        self.0.nth(n)
+    }
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<A: TrustedStep> TrustedLen for IterRangeFrom<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> FusedIterator for IterRangeFrom<A> {}
+
+#[unstable(feature = "new_range_api", issue = "125687")]
+impl<A: Step> IntoIterator for RangeFrom<A> {
+    type Item = A;
+    type IntoIter = IterRangeFrom<A>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterRangeFrom(self.into())
+    }
+}
diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs
new file mode 100644
index 00000000000..6723c4903f7
--- /dev/null
+++ b/library/core/src/range/legacy.rs
@@ -0,0 +1,10 @@
+//! # Legacy range types
+//!
+//! The types within this module will be replaced by the types
+//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent
+//! module, [`core::range`].
+//!
+//! The types here are equivalent to those in [`core::ops`].
+
+#[doc(inline)]
+pub use crate::ops::{Range, RangeFrom, RangeInclusive};
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 143dbd8a496..2624a44bb4b 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -2,6 +2,7 @@
 
 use crate::intrinsics::const_eval_select;
 use crate::ops;
+use crate::range;
 use crate::ub_checks::assert_unsafe_precondition;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -147,7 +148,8 @@ const unsafe fn get_offset_len_mut_noubcheck<T>(
 }
 
 mod private_slice_index {
-    use super::ops;
+    use super::{ops, range};
+
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
     pub trait Sealed {}
 
@@ -168,6 +170,13 @@ mod private_slice_index {
     #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
     impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
 
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::Range<usize> {}
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::RangeInclusive<usize> {}
+    #[unstable(feature = "new_range_api", issue = "125687")]
+    impl Sealed for range::RangeFrom<usize> {}
+
     impl Sealed for ops::IndexRange {}
 }
 
@@ -473,6 +482,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::Range::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::Range::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::Range::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline(always)]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::Range::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::Range::from(self).index_mut(slice)
+    }
+}
+
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
@@ -559,6 +605,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::RangeFrom::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::RangeFrom::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::RangeFrom::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::RangeFrom::from(self).index_mut(slice)
+    }
+}
+
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
 unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
@@ -643,6 +726,43 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
+    type Output = [T];
+
+    #[inline]
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        ops::RangeInclusive::from(self).get(slice)
+    }
+
+    #[inline]
+    fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
+        ops::RangeInclusive::from(self).get_mut(slice)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
+    }
+
+    #[inline]
+    fn index(self, slice: &[T]) -> &[T] {
+        ops::RangeInclusive::from(self).index(slice)
+    }
+
+    #[inline]
+    fn index_mut(self, slice: &mut [T]) -> &mut [T] {
+        ops::RangeInclusive::from(self).index_mut(slice)
+    }
+}
+
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 #[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
@@ -780,7 +900,7 @@ where
 
 /// Performs bounds-checking of a range without panicking.
 ///
-/// This is a version of [`range`] that returns [`None`] instead of panicking.
+/// This is a version of [`range()`] that returns [`None`] instead of panicking.
 ///
 /// # Examples
 ///
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index ba2d6f64496..3de5546c4d4 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -4,6 +4,7 @@ use crate::cmp::Ordering;
 use crate::intrinsics::unchecked_sub;
 use crate::ops;
 use crate::ptr;
+use crate::range;
 use crate::slice::SliceIndex;
 use crate::ub_checks::assert_unsafe_precondition;
 
@@ -261,6 +262,108 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::Range<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            // We also checked char boundaries, so this is valid UTF-8.
+            Some(unsafe { &*self.get_unchecked(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary.
+            // We know the pointer is unique because we got it from `slice`.
+            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        let slice = slice as *const [u8];
+
+        assert_unsafe_precondition!(
+            // We'd like to check that the bounds are on char boundaries,
+            // but there's not really a way to do so without reading
+            // behind the pointer, which has aliasing implications.
+            // It's also not possible to move this check up to
+            // `str::get_unchecked` without adding a special function
+            // to `SliceIndex` just for this.
+            check_library_ub,
+            "str::get_unchecked requires that the range is within the string slice",
+            (
+                start: usize = self.start,
+                end: usize = self.end,
+                len: usize = slice.len()
+            ) => end >= start && end <= len,
+        );
+
+        // SAFETY: the caller guarantees that `self` is in bounds of `slice`
+        // which satisfies all the conditions for `add`.
+        unsafe {
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        let slice = slice as *mut [u8];
+
+        assert_unsafe_precondition!(
+            check_library_ub,
+            "str::get_unchecked_mut requires that the range is within the string slice",
+            (
+                start: usize = self.start,
+                end: usize = self.end,
+                len: usize = slice.len()
+            ) => end >= start && end <= len,
+        );
+
+        // SAFETY: see comments for `get_unchecked`.
+        unsafe {
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str
+        }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        let (start, end) = (self.start, self.end);
+        match self.get(slice) {
+            Some(s) => s,
+            None => super::slice_error_fail(slice, start, end),
+        }
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        // is_char_boundary checks that the index is in [0, .len()]
+        // cannot reuse `get` as above, because of NLL trouble
+        if self.start <= self.end
+            && slice.is_char_boundary(self.start)
+            && slice.is_char_boundary(self.end)
+        {
+            // SAFETY: just checked that `start` and `end` are on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            unsafe { &mut *self.get_unchecked_mut(slice) }
+        } else {
+            super::slice_error_fail(slice, self.start, self.end)
+        }
+    }
+}
+
 /// Implements substring slicing for arbitrary bounds.
 ///
 /// Returns a slice of the given string bounded by the byte indices
@@ -453,6 +556,61 @@ unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::RangeFrom<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            Some(unsafe { &*self.get_unchecked(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            Some(unsafe { &mut *self.get_unchecked_mut(slice) })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        let len = (slice as *const [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
+        unsafe { (self.start..len).get_unchecked(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        let len = (slice as *mut [u8]).len();
+        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
+        unsafe { (self.start..len).get_unchecked_mut(slice) }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        let (start, end) = (self.start, slice.len());
+        match self.get(slice) {
+            Some(s) => s,
+            None => super::slice_error_fail(slice, start, end),
+        }
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        if slice.is_char_boundary(self.start) {
+            // SAFETY: just checked that `start` is on a char boundary,
+            // and we are passing in a safe reference, so the return value will also be one.
+            unsafe { &mut *self.get_unchecked_mut(slice) }
+        } else {
+            super::slice_error_fail(slice, self.start, slice.len())
+        }
+    }
+}
+
 /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
 /// self[begin ..= end]`.
 ///
@@ -507,6 +665,43 @@ unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
     }
 }
 
+#[unstable(feature = "new_range_api", issue = "125687")]
+unsafe impl SliceIndex<str> for range::RangeInclusive<usize> {
+    type Output = str;
+    #[inline]
+    fn get(self, slice: &str) -> Option<&Self::Output> {
+        if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) }
+    }
+    #[inline]
+    fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+        if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
+        unsafe { self.into_slice_range().get_unchecked(slice) }
+    }
+    #[inline]
+    unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
+        // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
+        unsafe { self.into_slice_range().get_unchecked_mut(slice) }
+    }
+    #[inline]
+    fn index(self, slice: &str) -> &Self::Output {
+        if self.end == usize::MAX {
+            str_index_overflow_fail();
+        }
+        self.into_slice_range().index(slice)
+    }
+    #[inline]
+    fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+        if self.end == usize::MAX {
+            str_index_overflow_fail();
+        }
+        self.into_slice_range().index_mut(slice)
+    }
+}
+
 /// Implements substring slicing with syntax `&self[..= end]` or `&mut
 /// self[..= end]`.
 ///
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index 4dc36120608..77abb9125f6 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -36,18 +36,14 @@ use core::panic::PanicPayload;
 cfg_if::cfg_if! {
     if #[cfg(target_os = "emscripten")] {
         #[path = "emcc.rs"]
-        mod real_imp;
+        mod imp;
     } else if #[cfg(target_os = "hermit")] {
         #[path = "hermit.rs"]
-        mod real_imp;
+        mod imp;
     } else if #[cfg(target_os = "l4re")] {
         // L4Re is unix family but does not yet support unwinding.
         #[path = "dummy.rs"]
-        mod real_imp;
-    } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
-        // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
-        #[path = "seh.rs"]
-        mod real_imp;
+        mod imp;
     } else if #[cfg(any(
         all(target_family = "windows", target_env = "gnu"),
         target_os = "psp",
@@ -58,7 +54,16 @@ cfg_if::cfg_if! {
         target_family = "wasm",
     ))] {
         #[path = "gcc.rs"]
-        mod real_imp;
+        mod imp;
+    } else if #[cfg(miri)] {
+        // Use the Miri runtime on Windows as miri doesn't support funclet based unwinding,
+        // only landingpad based unwinding. Also use the Miri runtime on unsupported platforms.
+        #[path = "miri.rs"]
+        mod imp;
+    } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] {
+        // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc)
+        #[path = "seh.rs"]
+        mod imp;
     } else {
         // Targets that don't support unwinding.
         // - os=none ("bare metal" targets)
@@ -67,20 +72,7 @@ cfg_if::cfg_if! {
         // - nvptx64-nvidia-cuda
         // - arch=avr
         #[path = "dummy.rs"]
-        mod real_imp;
-    }
-}
-
-cfg_if::cfg_if! {
-    if #[cfg(miri)] {
-        // Use the Miri runtime.
-        // We still need to also load the normal runtime above, as rustc expects certain lang
-        // items from there to be defined.
-        #[path = "miri.rs"]
         mod imp;
-    } else {
-        // Use the real runtime.
-        use real_imp as imp;
     }
 }
 
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index caae8f924d2..8d565e26a16 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1519,6 +1519,74 @@ impl PathBuf {
         true
     }
 
+    /// Append [`self.extension`] with `extension`.
+    ///
+    /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
+    /// returns `true` and updates the extension otherwise.
+    ///
+    /// # Caveats
+    ///
+    /// The appended `extension` may contain dots and will be used in its entirety,
+    /// but only the part after the final dot will be reflected in
+    /// [`self.extension`].
+    ///
+    /// See the examples below.
+    ///
+    /// [`self.file_name`]: Path::file_name
+    /// [`self.extension`]: Path::extension
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_add_extension)]
+    ///
+    /// use std::path::{Path, PathBuf};
+    ///
+    /// let mut p = PathBuf::from("/feel/the");
+    ///
+    /// p.add_extension("formatted");
+    /// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
+    ///
+    /// p.add_extension("dark.side");
+    /// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path());
+    ///
+    /// p.set_extension("cookie");
+    /// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path());
+    ///
+    /// p.set_extension("");
+    /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
+    ///
+    /// p.add_extension("");
+    /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
+    /// ```
+    #[unstable(feature = "path_add_extension", issue = "127292")]
+    pub fn add_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
+        self._add_extension(extension.as_ref())
+    }
+
+    fn _add_extension(&mut self, extension: &OsStr) -> bool {
+        let file_name = match self.file_name() {
+            None => return false,
+            Some(f) => f.as_encoded_bytes(),
+        };
+
+        let new = extension;
+        if !new.is_empty() {
+            // truncate until right after the file name
+            // this is necessary for trimming the trailing slash
+            let end_file_name = file_name[file_name.len()..].as_ptr().addr();
+            let start = self.inner.as_encoded_bytes().as_ptr().addr();
+            self.inner.truncate(end_file_name.wrapping_sub(start));
+
+            // append the new extension
+            self.inner.reserve_exact(new.len() + 1);
+            self.inner.push(OsStr::new("."));
+            self.inner.push(new);
+        }
+
+        true
+    }
+
     /// Yields a mutable reference to the underlying [`OsString`] instance.
     ///
     /// # Examples
@@ -2656,6 +2724,32 @@ impl Path {
         new_path
     }
 
+    /// Creates an owned [`PathBuf`] like `self` but with the extension added.
+    ///
+    /// See [`PathBuf::add_extension`] for more details.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_add_extension)]
+    ///
+    /// use std::path::{Path, PathBuf};
+    ///
+    /// let path = Path::new("foo.rs");
+    /// assert_eq!(path.with_added_extension("txt"), PathBuf::from("foo.rs.txt"));
+    ///
+    /// let path = Path::new("foo.tar.gz");
+    /// assert_eq!(path.with_added_extension(""), PathBuf::from("foo.tar.gz"));
+    /// assert_eq!(path.with_added_extension("xz"), PathBuf::from("foo.tar.gz.xz"));
+    /// assert_eq!(path.with_added_extension("").with_added_extension("txt"), PathBuf::from("foo.tar.gz.txt"));
+    /// ```
+    #[unstable(feature = "path_add_extension", issue = "127292")]
+    pub fn with_added_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
+        let mut new_path = self.to_path_buf();
+        new_path.add_extension(extension);
+        new_path
+    }
+
     /// Produces an iterator over the [`Component`]s of the path.
     ///
     /// When parsing the path, there is a small amount of normalization:
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index 92702b395df..bb6126e4941 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1402,6 +1402,37 @@ pub fn test_set_extension() {
 }
 
 #[test]
+pub fn test_add_extension() {
+    macro_rules! tfe (
+        ($path:expr, $ext:expr, $expected:expr, $output:expr) => ({
+            let mut p = PathBuf::from($path);
+            let output = p.add_extension($ext);
+            assert!(p.to_str() == Some($expected) && output == $output,
+                    "adding extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
+                    $path, $ext, $expected, $output,
+                    p.to_str().unwrap(), output);
+        });
+    );
+
+    tfe!("foo", "txt", "foo.txt", true);
+    tfe!("foo.bar", "txt", "foo.bar.txt", true);
+    tfe!("foo.bar.baz", "txt", "foo.bar.baz.txt", true);
+    tfe!(".test", "txt", ".test.txt", true);
+    tfe!("foo.txt", "", "foo.txt", true);
+    tfe!("foo", "", "foo", true);
+    tfe!("", "foo", "", false);
+    tfe!(".", "foo", ".", false);
+    tfe!("foo/", "bar", "foo.bar", true);
+    tfe!("foo/.", "bar", "foo.bar", true);
+    tfe!("..", "foo", "..", false);
+    tfe!("foo/..", "bar", "foo/..", false);
+    tfe!("/", "foo", "/", false);
+
+    // edge cases
+    tfe!("/foo.ext////", "bar", "/foo.ext.bar", true);
+}
+
+#[test]
 pub fn test_with_extension() {
     macro_rules! twe (
         ($input:expr, $extension:expr, $expected:expr) => ({
@@ -1442,6 +1473,49 @@ pub fn test_with_extension() {
 }
 
 #[test]
+pub fn test_with_added_extension() {
+    macro_rules! twe (
+        ($input:expr, $extension:expr, $expected:expr) => ({
+            let input = Path::new($input);
+            let output = input.with_added_extension($extension);
+
+            assert!(
+                output.to_str() == Some($expected),
+                "calling Path::new({:?}).with_added_extension({:?}): Expected {:?}, got {:?}",
+                $input, $extension, $expected, output,
+            );
+        });
+    );
+
+    twe!("foo", "txt", "foo.txt");
+    twe!("foo.bar", "txt", "foo.bar.txt");
+    twe!("foo.bar.baz", "txt", "foo.bar.baz.txt");
+    twe!(".test", "txt", ".test.txt");
+    twe!("foo.txt", "", "foo.txt");
+    twe!("foo", "", "foo");
+    twe!("", "foo", "");
+    twe!(".", "foo", ".");
+    twe!("foo/", "bar", "foo.bar");
+    twe!("foo/.", "bar", "foo.bar");
+    twe!("..", "foo", "..");
+    twe!("foo/..", "bar", "foo/..");
+    twe!("/", "foo", "/");
+
+    // edge cases
+    twe!("/foo.ext////", "bar", "/foo.ext.bar");
+
+    // New extension is smaller than file name
+    twe!("aaa_aaa_aaa", "bbb_bbb", "aaa_aaa_aaa.bbb_bbb");
+    // New extension is greater than file name
+    twe!("bbb_bbb", "aaa_aaa_aaa", "bbb_bbb.aaa_aaa_aaa");
+
+    // New extension is smaller than previous extension
+    twe!("ccc.aaa_aaa_aaa", "bbb_bbb", "ccc.aaa_aaa_aaa.bbb_bbb");
+    // New extension is greater than previous extension
+    twe!("ccc.bbb_bbb", "aaa_aaa_aaa", "ccc.bbb_bbb.aaa_aaa_aaa");
+}
+
+#[test]
 fn test_eq_receivers() {
     use crate::borrow::Cow;
 
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 6ec82693077..27aa35f69f1 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -13,6 +13,8 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo
 use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
 use crate::ptr;
 
+mod windows_targets;
+
 mod windows_sys;
 pub use windows_sys::*;
 
@@ -504,11 +506,8 @@ if #[cfg(not(target_vendor = "uwp"))] {
     #[cfg(target_arch = "arm")]
     pub enum CONTEXT {}
 }}
-
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32;
-}
+// WSAStartup is only redefined here so that we can override WSADATA for Arm32
+windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32);
 #[cfg(target_arch = "arm")]
 #[repr(C)]
 pub struct WSADATA {
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 849e64ac591..5ad4a3731d8 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -1,5 +1,5 @@
 --out windows_sys.rs
---config flatten std
+--config flatten sys
 --filter
 !Windows.Win32.Foundation.INVALID_HANDLE_VALUE
 Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 19f013d3347..fea00fec9ae 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -1,843 +1,136 @@
-// Bindings generated by `windows-bindgen` 0.57.0
+// Bindings generated by `windows-bindgen` 0.58.0
 
 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
-#[link(name = "advapi32")]
-extern "system" {
-    pub fn OpenProcessToken(
-        processhandle: HANDLE,
-        desiredaccess: TOKEN_ACCESS_MASK,
-        tokenhandle: *mut HANDLE,
-    ) -> BOOL;
-}
-#[link(name = "advapi32")]
-extern "system" {
-    #[link_name = "SystemFunction036"]
-    pub fn RtlGenRandom(randombuffer: *mut core::ffi::c_void, randombufferlength: u32) -> BOOLEAN;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CancelIo(hfile: HANDLE) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CloseHandle(hobject: HANDLE) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CompareStringOrdinal(
-        lpstring1: PCWSTR,
-        cchcount1: i32,
-        lpstring2: PCWSTR,
-        cchcount2: i32,
-        bignorecase: BOOL,
-    ) -> COMPARESTRING_RESULT;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CopyFileExW(
-        lpexistingfilename: PCWSTR,
-        lpnewfilename: PCWSTR,
-        lpprogressroutine: LPPROGRESS_ROUTINE,
-        lpdata: *const core::ffi::c_void,
-        pbcancel: *mut BOOL,
-        dwcopyflags: u32,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateDirectoryW(
-        lppathname: PCWSTR,
-        lpsecurityattributes: *const SECURITY_ATTRIBUTES,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateEventW(
-        lpeventattributes: *const SECURITY_ATTRIBUTES,
-        bmanualreset: BOOL,
-        binitialstate: BOOL,
-        lpname: PCWSTR,
-    ) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateFileW(
-        lpfilename: PCWSTR,
-        dwdesiredaccess: u32,
-        dwsharemode: FILE_SHARE_MODE,
-        lpsecurityattributes: *const SECURITY_ATTRIBUTES,
-        dwcreationdisposition: FILE_CREATION_DISPOSITION,
-        dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES,
-        htemplatefile: HANDLE,
-    ) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateHardLinkW(
-        lpfilename: PCWSTR,
-        lpexistingfilename: PCWSTR,
-        lpsecurityattributes: *const SECURITY_ATTRIBUTES,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateNamedPipeW(
-        lpname: PCWSTR,
-        dwopenmode: FILE_FLAGS_AND_ATTRIBUTES,
-        dwpipemode: NAMED_PIPE_MODE,
-        nmaxinstances: u32,
-        noutbuffersize: u32,
-        ninbuffersize: u32,
-        ndefaulttimeout: u32,
-        lpsecurityattributes: *const SECURITY_ATTRIBUTES,
-    ) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateProcessW(
-        lpapplicationname: PCWSTR,
-        lpcommandline: PWSTR,
-        lpprocessattributes: *const SECURITY_ATTRIBUTES,
-        lpthreadattributes: *const SECURITY_ATTRIBUTES,
-        binherithandles: BOOL,
-        dwcreationflags: PROCESS_CREATION_FLAGS,
-        lpenvironment: *const core::ffi::c_void,
-        lpcurrentdirectory: PCWSTR,
-        lpstartupinfo: *const STARTUPINFOW,
-        lpprocessinformation: *mut PROCESS_INFORMATION,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateSymbolicLinkW(
-        lpsymlinkfilename: PCWSTR,
-        lptargetfilename: PCWSTR,
-        dwflags: SYMBOLIC_LINK_FLAGS,
-    ) -> BOOLEAN;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateThread(
-        lpthreadattributes: *const SECURITY_ATTRIBUTES,
-        dwstacksize: usize,
-        lpstartaddress: LPTHREAD_START_ROUTINE,
-        lpparameter: *const core::ffi::c_void,
-        dwcreationflags: THREAD_CREATION_FLAGS,
-        lpthreadid: *mut u32,
-    ) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn CreateWaitableTimerExW(
-        lptimerattributes: *const SECURITY_ATTRIBUTES,
-        lptimername: PCWSTR,
-        dwflags: u32,
-        dwdesiredaccess: u32,
-    ) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn DeleteFileW(lpfilename: PCWSTR) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn DeleteProcThreadAttributeList(lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn DeviceIoControl(
-        hdevice: HANDLE,
-        dwiocontrolcode: u32,
-        lpinbuffer: *const core::ffi::c_void,
-        ninbuffersize: u32,
-        lpoutbuffer: *mut core::ffi::c_void,
-        noutbuffersize: u32,
-        lpbytesreturned: *mut u32,
-        lpoverlapped: *mut OVERLAPPED,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn DuplicateHandle(
-        hsourceprocesshandle: HANDLE,
-        hsourcehandle: HANDLE,
-        htargetprocesshandle: HANDLE,
-        lptargethandle: *mut HANDLE,
-        dwdesiredaccess: u32,
-        binherithandle: BOOL,
-        dwoptions: DUPLICATE_HANDLE_OPTIONS,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ExitProcess(uexitcode: u32) -> !;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FindClose(hfindfile: HANDLE) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FlushFileBuffers(hfile: HANDLE) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FormatMessageW(
-        dwflags: FORMAT_MESSAGE_OPTIONS,
-        lpsource: *const core::ffi::c_void,
-        dwmessageid: u32,
-        dwlanguageid: u32,
-        lpbuffer: PWSTR,
-        nsize: u32,
-        arguments: *const *const i8,
-    ) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetActiveProcessorCount(groupnumber: u16) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetCommandLineW() -> PCWSTR;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetConsoleMode(hconsolehandle: HANDLE, lpmode: *mut CONSOLE_MODE) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetCurrentDirectoryW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetCurrentProcess() -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetCurrentProcessId() -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetCurrentThread() -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetEnvironmentStringsW() -> PWSTR;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetEnvironmentVariableW(lpname: PCWSTR, lpbuffer: PWSTR, nsize: u32) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetExitCodeProcess(hprocess: HANDLE, lpexitcode: *mut u32) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFileAttributesW(lpfilename: PCWSTR) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFileInformationByHandle(
-        hfile: HANDLE,
-        lpfileinformation: *mut BY_HANDLE_FILE_INFORMATION,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFileInformationByHandleEx(
-        hfile: HANDLE,
-        fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
-        lpfileinformation: *mut core::ffi::c_void,
-        dwbuffersize: u32,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFileType(hfile: HANDLE) -> FILE_TYPE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFinalPathNameByHandleW(
-        hfile: HANDLE,
-        lpszfilepath: PWSTR,
-        cchfilepath: u32,
-        dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS,
-    ) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetFullPathNameW(
-        lpfilename: PCWSTR,
-        nbufferlength: u32,
-        lpbuffer: PWSTR,
-        lpfilepart: *mut PWSTR,
-    ) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetLastError() -> WIN32_ERROR;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetModuleFileNameW(hmodule: HMODULE, lpfilename: PWSTR, nsize: u32) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetModuleHandleW(lpmodulename: PCWSTR) -> HMODULE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetOverlappedResult(
-        hfile: HANDLE,
-        lpoverlapped: *const OVERLAPPED,
-        lpnumberofbytestransferred: *mut u32,
-        bwait: BOOL,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetProcessId(process: HANDLE) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetStdHandle(nstdhandle: STD_HANDLE) -> HANDLE;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn GetWindowsDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn InitOnceBeginInitialize(
-        lpinitonce: *mut INIT_ONCE,
-        dwflags: u32,
-        fpending: *mut BOOL,
-        lpcontext: *mut *mut core::ffi::c_void,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn InitOnceComplete(
-        lpinitonce: *mut INIT_ONCE,
-        dwflags: u32,
-        lpcontext: *const core::ffi::c_void,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn InitializeProcThreadAttributeList(
-        lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
-        dwattributecount: u32,
-        dwflags: u32,
-        lpsize: *mut usize,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn LocalFree(hmem: HLOCAL) -> HLOCAL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn MoveFileExW(
-        lpexistingfilename: PCWSTR,
-        lpnewfilename: PCWSTR,
-        dwflags: MOVE_FILE_FLAGS,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn MultiByteToWideChar(
-        codepage: u32,
-        dwflags: MULTI_BYTE_TO_WIDE_CHAR_FLAGS,
-        lpmultibytestr: PCSTR,
-        cbmultibyte: i32,
-        lpwidecharstr: PWSTR,
-        cchwidechar: i32,
-    ) -> i32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ReadConsoleW(
-        hconsoleinput: HANDLE,
-        lpbuffer: *mut core::ffi::c_void,
-        nnumberofcharstoread: u32,
-        lpnumberofcharsread: *mut u32,
-        pinputcontrol: *const CONSOLE_READCONSOLE_CONTROL,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ReadFile(
-        hfile: HANDLE,
-        lpbuffer: *mut u8,
-        nnumberofbytestoread: u32,
-        lpnumberofbytesread: *mut u32,
-        lpoverlapped: *mut OVERLAPPED,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ReadFileEx(
-        hfile: HANDLE,
-        lpbuffer: *mut u8,
-        nnumberofbytestoread: u32,
-        lpoverlapped: *mut OVERLAPPED,
-        lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetCurrentDirectoryW(lppathname: PCWSTR) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetEnvironmentVariableW(lpname: PCWSTR, lpvalue: PCWSTR) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetFileAttributesW(
-        lpfilename: PCWSTR,
-        dwfileattributes: FILE_FLAGS_AND_ATTRIBUTES,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetFileInformationByHandle(
-        hfile: HANDLE,
-        fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
-        lpfileinformation: *const core::ffi::c_void,
-        dwbuffersize: u32,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetFilePointerEx(
-        hfile: HANDLE,
-        lidistancetomove: i64,
-        lpnewfilepointer: *mut i64,
-        dwmovemethod: SET_FILE_POINTER_MOVE_METHOD,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetFileTime(
-        hfile: HANDLE,
-        lpcreationtime: *const FILETIME,
-        lplastaccesstime: *const FILETIME,
-        lplastwritetime: *const FILETIME,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetLastError(dwerrcode: WIN32_ERROR);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SetWaitableTimer(
-        htimer: HANDLE,
-        lpduetime: *const i64,
-        lperiod: i32,
-        pfncompletionroutine: PTIMERAPCROUTINE,
-        lpargtocompletionroutine: *const core::ffi::c_void,
-        fresume: BOOL,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn Sleep(dwmilliseconds: u32);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SleepConditionVariableSRW(
-        conditionvariable: *mut CONDITION_VARIABLE,
-        srwlock: *mut SRWLOCK,
-        dwmilliseconds: u32,
-        flags: u32,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn SwitchToThread() -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TerminateProcess(hprocess: HANDLE, uexitcode: u32) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TlsAlloc() -> u32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TlsFree(dwtlsindex: u32) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TlsGetValue(dwtlsindex: u32) -> *mut core::ffi::c_void;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const core::ffi::c_void) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn UpdateProcThreadAttribute(
-        lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
-        dwflags: u32,
-        attribute: usize,
-        lpvalue: *const core::ffi::c_void,
-        cbsize: usize,
-        lppreviousvalue: *mut core::ffi::c_void,
-        lpreturnsize: *const usize,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WaitForMultipleObjects(
-        ncount: u32,
-        lphandles: *const HANDLE,
-        bwaitall: BOOL,
-        dwmilliseconds: u32,
-    ) -> WAIT_EVENT;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE);
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WideCharToMultiByte(
-        codepage: u32,
-        dwflags: u32,
-        lpwidecharstr: PCWSTR,
-        cchwidechar: i32,
-        lpmultibytestr: PSTR,
-        cbmultibyte: i32,
-        lpdefaultchar: PCSTR,
-        lpuseddefaultchar: *mut BOOL,
-    ) -> i32;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WriteConsoleW(
-        hconsoleoutput: HANDLE,
-        lpbuffer: *const core::ffi::c_void,
-        nnumberofcharstowrite: u32,
-        lpnumberofcharswritten: *mut u32,
-        lpreserved: *const core::ffi::c_void,
-    ) -> BOOL;
-}
-#[link(name = "kernel32")]
-extern "system" {
-    pub fn WriteFileEx(
-        hfile: HANDLE,
-        lpbuffer: *const u8,
-        nnumberofbytestowrite: u32,
-        lpoverlapped: *mut OVERLAPPED,
-        lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
-    ) -> BOOL;
-}
-#[link(name = "ntdll")]
-extern "system" {
-    pub fn NtCreateFile(
-        filehandle: *mut HANDLE,
-        desiredaccess: FILE_ACCESS_RIGHTS,
-        objectattributes: *const OBJECT_ATTRIBUTES,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        allocationsize: *const i64,
-        fileattributes: FILE_FLAGS_AND_ATTRIBUTES,
-        shareaccess: FILE_SHARE_MODE,
-        createdisposition: NTCREATEFILE_CREATE_DISPOSITION,
-        createoptions: NTCREATEFILE_CREATE_OPTIONS,
-        eabuffer: *const core::ffi::c_void,
-        ealength: u32,
-    ) -> NTSTATUS;
-}
-#[link(name = "ntdll")]
-extern "system" {
-    pub fn NtReadFile(
-        filehandle: HANDLE,
-        event: HANDLE,
-        apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const core::ffi::c_void,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *mut core::ffi::c_void,
-        length: u32,
-        byteoffset: *const i64,
-        key: *const u32,
-    ) -> NTSTATUS;
-}
-#[link(name = "ntdll")]
-extern "system" {
-    pub fn NtWriteFile(
-        filehandle: HANDLE,
-        event: HANDLE,
-        apcroutine: PIO_APC_ROUTINE,
-        apccontext: *const core::ffi::c_void,
-        iostatusblock: *mut IO_STATUS_BLOCK,
-        buffer: *const core::ffi::c_void,
-        length: u32,
-        byteoffset: *const i64,
-        key: *const u32,
-    ) -> NTSTATUS;
-}
-#[link(name = "ntdll")]
-extern "system" {
-    pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32;
-}
-#[link(name = "userenv")]
-extern "system" {
-    pub fn GetUserProfileDirectoryW(
-        htoken: HANDLE,
-        lpprofiledir: PWSTR,
-        lpcchsize: *mut u32,
-    ) -> BOOL;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSACleanup() -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSADuplicateSocketW(
-        s: SOCKET,
-        dwprocessid: u32,
-        lpprotocolinfo: *mut WSAPROTOCOL_INFOW,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSAGetLastError() -> WSA_ERROR;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSARecv(
-        s: SOCKET,
-        lpbuffers: *const WSABUF,
-        dwbuffercount: u32,
-        lpnumberofbytesrecvd: *mut u32,
-        lpflags: *mut u32,
-        lpoverlapped: *mut OVERLAPPED,
-        lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSASend(
-        s: SOCKET,
-        lpbuffers: *const WSABUF,
-        dwbuffercount: u32,
-        lpnumberofbytessent: *mut u32,
-        dwflags: u32,
-        lpoverlapped: *mut OVERLAPPED,
-        lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn WSASocketW(
-        af: i32,
-        r#type: i32,
-        protocol: i32,
-        lpprotocolinfo: *const WSAPROTOCOL_INFOW,
-        g: u32,
-        dwflags: u32,
-    ) -> SOCKET;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut i32) -> SOCKET;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn closesocket(s: SOCKET) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA);
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn getaddrinfo(
-        pnodename: PCSTR,
-        pservicename: PCSTR,
-        phints: *const ADDRINFOA,
-        ppresult: *mut *mut ADDRINFOA,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn getsockopt(s: SOCKET, level: i32, optname: i32, optval: PSTR, optlen: *mut i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn ioctlsocket(s: SOCKET, cmd: i32, argp: *mut u32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn listen(s: SOCKET, backlog: i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn recv(s: SOCKET, buf: PSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn recvfrom(
-        s: SOCKET,
-        buf: PSTR,
-        len: i32,
-        flags: i32,
-        from: *mut SOCKADDR,
-        fromlen: *mut i32,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn select(
-        nfds: i32,
-        readfds: *mut FD_SET,
-        writefds: *mut FD_SET,
-        exceptfds: *mut FD_SET,
-        timeout: *const TIMEVAL,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn send(s: SOCKET, buf: PCSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn sendto(
-        s: SOCKET,
-        buf: PCSTR,
-        len: i32,
-        flags: i32,
-        to: *const SOCKADDR,
-        tolen: i32,
-    ) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn setsockopt(s: SOCKET, level: i32, optname: i32, optval: PCSTR, optlen: i32) -> i32;
-}
-#[link(name = "ws2_32")]
-extern "system" {
-    pub fn shutdown(s: SOCKET, how: WINSOCK_SHUTDOWN_HOW) -> i32;
-}
+windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL);
+windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
+windows_targets::link!("kernel32.dll" "system" fn CopyFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, lpprogressroutine : LPPROGRESS_ROUTINE, lpdata : *const core::ffi::c_void, pbcancel : *mut BOOL, dwcopyflags : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateDirectoryW(lppathname : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn CreateFileW(lpfilename : PCWSTR, dwdesiredaccess : u32, dwsharemode : FILE_SHARE_MODE, lpsecurityattributes : *const SECURITY_ATTRIBUTES, dwcreationdisposition : FILE_CREATION_DISPOSITION, dwflagsandattributes : FILE_FLAGS_AND_ATTRIBUTES, htemplatefile : HANDLE) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn CreateHardLinkW(lpfilename : PCWSTR, lpexistingfilename : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateNamedPipeW(lpname : PCWSTR, dwopenmode : FILE_FLAGS_AND_ATTRIBUTES, dwpipemode : NAMED_PIPE_MODE, nmaxinstances : u32, noutbuffersize : u32, ninbuffersize : u32, ndefaulttimeout : u32, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn CreateProcessW(lpapplicationname : PCWSTR, lpcommandline : PWSTR, lpprocessattributes : *const SECURITY_ATTRIBUTES, lpthreadattributes : *const SECURITY_ATTRIBUTES, binherithandles : BOOL, dwcreationflags : PROCESS_CREATION_FLAGS, lpenvironment : *const core::ffi::c_void, lpcurrentdirectory : PCWSTR, lpstartupinfo : *const STARTUPINFOW, lpprocessinformation : *mut PROCESS_INFORMATION) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateSymbolicLinkW(lpsymlinkfilename : PCWSTR, lptargetfilename : PCWSTR, dwflags : SYMBOLIC_LINK_FLAGS) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn CreateThread(lpthreadattributes : *const SECURITY_ATTRIBUTES, dwstacksize : usize, lpstartaddress : LPTHREAD_START_ROUTINE, lpparameter : *const core::ffi::c_void, dwcreationflags : THREAD_CREATION_FLAGS, lpthreadid : *mut u32) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn CreateWaitableTimerExW(lptimerattributes : *const SECURITY_ATTRIBUTES, lptimername : PCWSTR, dwflags : u32, dwdesiredaccess : u32) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn DeleteFileW(lpfilename : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn DeleteProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST));
+windows_targets::link!("kernel32.dll" "system" fn DeviceIoControl(hdevice : HANDLE, dwiocontrolcode : u32, lpinbuffer : *const core::ffi::c_void, ninbuffersize : u32, lpoutbuffer : *mut core::ffi::c_void, noutbuffersize : u32, lpbytesreturned : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn DuplicateHandle(hsourceprocesshandle : HANDLE, hsourcehandle : HANDLE, htargetprocesshandle : HANDLE, lptargethandle : *mut HANDLE, dwdesiredaccess : u32, binherithandle : BOOL, dwoptions : DUPLICATE_HANDLE_OPTIONS) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ExitProcess(uexitcode : u32) -> !);
+windows_targets::link!("kernel32.dll" "system" fn FindClose(hfindfile : HANDLE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn FindFirstFileW(lpfilename : PCWSTR, lpfindfiledata : *mut WIN32_FIND_DATAW) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn FindNextFileW(hfindfile : HANDLE, lpfindfiledata : *mut WIN32_FIND_DATAW) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn FlushFileBuffers(hfile : HANDLE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR);
+windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetCurrentThread() -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentStringsW() -> PWSTR);
+windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentVariableW(lpname : PCWSTR, lpbuffer : PWSTR, nsize : u32) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : HANDLE, lpexitcode : *mut u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE);
+windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR);
+windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(hmodule : HMODULE, lpfilename : PWSTR, nsize : u32) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpmodulename : PCSTR) -> HMODULE);
+windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleW(lpmodulename : PCWSTR) -> HMODULE);
+windows_targets::link!("kernel32.dll" "system" fn GetOverlappedResult(hfile : HANDLE, lpoverlapped : *const OVERLAPPED, lpnumberofbytestransferred : *mut u32, bwait : BOOL) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC);
+windows_targets::link!("kernel32.dll" "system" fn GetProcessId(process : HANDLE) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetStdHandle(nstdhandle : STD_HANDLE) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn GetSystemDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetSystemInfo(lpsysteminfo : *mut SYSTEM_INFO));
+windows_targets::link!("kernel32.dll" "system" fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
+windows_targets::link!("kernel32.dll" "system" fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
+windows_targets::link!("kernel32.dll" "system" fn GetTempPathW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetWindowsDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinitonce : *mut INIT_ONCE, dwflags : u32, fpending : *mut BOOL, lpcontext : *mut *mut core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
+windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32);
+windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceFrequency(lpfrequency : *mut i64) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ReadConsoleW(hconsoleinput : HANDLE, lpbuffer : *mut core::ffi::c_void, nnumberofcharstoread : u32, lpnumberofcharsread : *mut u32, pinputcontrol : *const CONSOLE_READCONSOLE_CONTROL) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ReadFile(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpnumberofbytesread : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ReadFileEx(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockExclusive(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockShared(srwlock : *mut SRWLOCK));
+windows_targets::link!("kernel32.dll" "system" fn RemoveDirectoryW(lppathname : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetCurrentDirectoryW(lppathname : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetEnvironmentVariableW(lpname : PCWSTR, lpvalue : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetFileAttributesW(lpfilename : PCWSTR, dwfileattributes : FILE_FLAGS_AND_ATTRIBUTES) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetFileInformationByHandle(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *const core::ffi::c_void, dwbuffersize : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetFilePointerEx(hfile : HANDLE, lidistancetomove : i64, lpnewfilepointer : *mut i64, dwmovemethod : SET_FILE_POINTER_MOVE_METHOD) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetFileTime(hfile : HANDLE, lpcreationtime : *const FILETIME, lplastaccesstime : *const FILETIME, lplastwritetime : *const FILETIME) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetHandleInformation(hobject : HANDLE, dwmask : u32, dwflags : HANDLE_FLAGS) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetLastError(dwerrcode : WIN32_ERROR));
+windows_targets::link!("kernel32.dll" "system" fn SetThreadStackGuarantee(stacksizeinbytes : *mut u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetWaitableTimer(htimer : HANDLE, lpduetime : *const i64, lperiod : i32, pfncompletionroutine : PTIMERAPCROUTINE, lpargtocompletionroutine : *const core::ffi::c_void, fresume : BOOL) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
+windows_targets::link!("kernel32.dll" "system" fn SleepConditionVariableSRW(conditionvariable : *mut CONDITION_VARIABLE, srwlock : *mut SRWLOCK, dwmilliseconds : u32, flags : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SleepEx(dwmilliseconds : u32, balertable : BOOL) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn SwitchToThread() -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn TerminateProcess(hprocess : HANDLE, uexitcode : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn TlsAlloc() -> u32);
+windows_targets::link!("kernel32.dll" "system" fn TlsFree(dwtlsindex : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32) -> *mut core::ffi::c_void);
+windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn UpdateProcThreadAttribute(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwflags : u32, attribute : usize, lpvalue : *const core::ffi::c_void, cbsize : usize, lppreviousvalue : *mut core::ffi::c_void, lpreturnsize : *const usize) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT);
+windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
+windows_targets::link!("kernel32.dll" "system" fn WakeAllConditionVariable(conditionvariable : *mut CONDITION_VARIABLE));
+windows_targets::link!("kernel32.dll" "system" fn WakeConditionVariable(conditionvariable : *mut CONDITION_VARIABLE));
+windows_targets::link!("kernel32.dll" "system" fn WideCharToMultiByte(codepage : u32, dwflags : u32, lpwidecharstr : PCWSTR, cchwidechar : i32, lpmultibytestr : PSTR, cbmultibyte : i32, lpdefaultchar : PCSTR, lpuseddefaultchar : *mut BOOL) -> i32);
+windows_targets::link!("kernel32.dll" "system" fn WriteConsoleW(hconsoleoutput : HANDLE, lpbuffer : PCWSTR, nnumberofcharstowrite : u32, lpnumberofcharswritten : *mut u32, lpreserved : *const core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn WriteFileEx(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
+windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
+windows_targets::link!("userenv.dll" "system" fn GetUserProfileDirectoryW(htoken : HANDLE, lpprofiledir : PWSTR, lpcchsize : *mut u32) -> BOOL);
+windows_targets::link!("ws2_32.dll" "system" fn WSACleanup() -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSADuplicateSocketW(s : SOCKET, dwprocessid : u32, lpprotocolinfo : *mut WSAPROTOCOL_INFOW) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
+windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
+windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
+windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn connect(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn freeaddrinfo(paddrinfo : *const ADDRINFOA));
+windows_targets::link!("ws2_32.dll" "system" fn getaddrinfo(pnodename : PCSTR, pservicename : PCSTR, phints : *const ADDRINFOA, ppresult : *mut *mut ADDRINFOA) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn getpeername(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn recvfrom(s : SOCKET, buf : PSTR, len : i32, flags : i32, from : *mut SOCKADDR, fromlen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn select(nfds : i32, readfds : *mut FD_SET, writefds : *mut FD_SET, exceptfds : *mut FD_SET, timeout : *const TIMEVAL) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn send(s : SOCKET, buf : PCSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn sendto(s : SOCKET, buf : PCSTR, len : i32, flags : i32, to : *const SOCKADDR, tolen : i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn setsockopt(s : SOCKET, level : i32, optname : i32, optval : PCSTR, optlen : i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn shutdown(s : SOCKET, how : WINSOCK_SHUTDOWN_HOW) -> i32);
 pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32;
 pub type ADDRESS_FAMILY = u16;
 #[repr(C)]
@@ -3991,3 +3284,4 @@ pub struct XSAVE_FORMAT {
     pub Reserved4: [u8; 224],
 }
 // ignore-tidy-filelength
+use super::windows_targets;
diff --git a/library/std/src/sys/pal/windows/c/windows_targets.rs b/library/std/src/sys/pal/windows/c/windows_targets.rs
new file mode 100644
index 00000000000..56c563462d3
--- /dev/null
+++ b/library/std/src/sys/pal/windows/c/windows_targets.rs
@@ -0,0 +1,24 @@
+//! Provides the `link!` macro used by the generated windows bindings.
+//!
+//! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
+//! It's very roughly equivalent to the windows-targets crate.
+
+pub macro link {
+    ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
+        // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
+        // have in this repo. So instead we always link kernel32.lib and add the rest of the import
+        // libraries below by using an empty extern block. This works because extern blocks are not
+        // connected to the library given in the #[link] attribute.
+        #[link(name = "kernel32")]
+        extern $abi {
+            $(#[link_name=$link_name])?
+            pub fn $($function)*;
+        }
+    )
+}
+
+#[link(name = "advapi32")]
+#[link(name = "ntdll")]
+#[link(name = "userenv")]
+#[link(name = "ws2_32")]
+extern "C" {}
diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs
index 690b60d1dec..10aeeac07ea 100644
--- a/library/std/src/sys/pal/windows/stdio.rs
+++ b/library/std/src/sys/pal/windows/stdio.rs
@@ -232,13 +232,7 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> {
     debug_assert!(data.len() < u32::MAX as usize);
     let mut written = 0;
     cvt(unsafe {
-        c::WriteConsoleW(
-            handle,
-            data.as_ptr() as c::LPCVOID,
-            data.len() as u32,
-            &mut written,
-            ptr::null_mut(),
-        )
+        c::WriteConsoleW(handle, data.as_ptr(), data.len() as u32, &mut written, ptr::null_mut())
     })?;
     Ok(written as usize)
 }
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index a4c59b3067e..695b8b4c0d9 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -93,8 +93,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
     docker --version
 
     REGISTRY=ghcr.io
-    # PR CI runs on rust-lang, but we want to use the cache from rust-lang-ci
-    REGISTRY_USERNAME=rust-lang-ci
+    REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER}
     # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
     IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
     # Tag used to cache the Docker build
diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py
index 4f9bc39a628..d03bbda1008 100755
--- a/src/ci/github-actions/calculate-job-matrix.py
+++ b/src/ci/github-actions/calculate-job-matrix.py
@@ -91,21 +91,17 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]:
     if ctx.event_name == "pull_request":
         return PRRunType()
     elif ctx.event_name == "push":
-        old_bors_try_build = (
-            ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and
-            ctx.repository == "rust-lang-ci/rust"
+        try_build = ctx.ref in (
+            "refs/heads/try",
+            "refs/heads/try-perf",
+            "refs/heads/automation/bors/try"
         )
-        new_bors_try_build = (
-            ctx.ref == "refs/heads/automation/bors/try" and
-            ctx.repository == "rust-lang/rust"
-        )
-        try_build = old_bors_try_build or new_bors_try_build
 
         if try_build:
             jobs = get_custom_jobs(ctx)
             return TryRunType(custom_jobs=jobs)
 
-        if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust":
+        if ctx.ref == "refs/heads/auto":
             return AutoRunType()
 
     return None
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index a0ab262bf0b..86af38f3ee7 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -3293,10 +3293,9 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         }
         // call after consuming `{`
         decodeList() {
-            const cb = "}".charCodeAt(0);
             let c = this.string.charCodeAt(this.offset);
             const ret = [];
-            while (c !== cb) {
+            while (c !== 125) { // 125 = "}"
                 ret.push(this.decode());
                 c = this.string.charCodeAt(this.offset);
             }
@@ -3305,14 +3304,13 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         }
         // consumes and returns a list or integer
         decode() {
-            const [ob, la] = ["{", "`"].map(c => c.charCodeAt(0));
             let n = 0;
             let c = this.string.charCodeAt(this.offset);
-            if (c === ob) {
+            if (c === 123) { // 123 = "{"
                 this.offset += 1;
                 return this.decodeList();
             }
-            while (c < la) {
+            while (c < 96) { // 96 = "`"
                 n = (n << 4) | (c & 0xF);
                 this.offset += 1;
                 c = this.string.charCodeAt(this.offset);
@@ -3325,15 +3323,14 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         }
         next() {
             const c = this.string.charCodeAt(this.offset);
-            const [zero, ua, la] = ["0", "@", "`"].map(c => c.charCodeAt(0));
             // sixteen characters after "0" are backref
-            if (c >= zero && c < ua) {
+            if (c >= 48 && c < 64) { // 48 = "0", 64 = "@"
                 this.offset += 1;
-                return this.backrefQueue[c - zero];
+                return this.backrefQueue[c - 48];
             }
             // special exception: 0 doesn't use backref encoding
             // it's already one character, and it's always nullish
-            if (c === la) {
+            if (c === 96) { // 96 = "`"
                 this.offset += 1;
                 return this.cons(0);
             }
@@ -3472,7 +3469,6 @@ ${item.displayPath}<span class="${type}">${name}</span>\
         searchIndex = [];
         searchIndexDeprecated = new Map();
         searchIndexEmptyDesc = new Map();
-        const charA = "A".charCodeAt(0);
         let currentIndex = 0;
         let id = 0;
 
@@ -3639,7 +3635,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
                 // object defined above.
                 const row = {
                     crate,
-                    ty: itemTypes.charCodeAt(i) - charA,
+                    ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
                     name: itemNames[i],
                     path,
                     descShard,
diff --git a/src/llvm-project b/src/llvm-project
-Subproject e6a6470d1eb4c88fee4b1ea98cd8e0ac4a181c1
+Subproject c54cff0e6e4d1a0d0a2df7c1ce3d96cdd554763
diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml
index ebf3082fb4f..882d3d63525 100644
--- a/src/tools/generate-windows-sys/Cargo.toml
+++ b/src/tools/generate-windows-sys/Cargo.toml
@@ -4,4 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies.windows-bindgen]
-version = "0.57.0"
+version = "0.58.0"
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
index c8913910bd6..fd21e7a86b0 100644
--- a/src/tools/generate-windows-sys/src/main.rs
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -17,6 +17,7 @@ fn main() -> Result<(), Box<dyn Error>> {
 
     let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?;
     writeln!(&mut f, "// ignore-tidy-filelength")?;
+    writeln!(&mut f, "use super::windows_targets;")?;
 
     Ok(())
 }
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 7321bd1bb52..72ae3ed26e8 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -59,6 +59,8 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[
     // This is being used in the sense of 'inclusive range', not a markdown link
     ("core/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
     ("std/ops/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
+    ("core/range/legacy/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
+    ("std/range/legacy/struct.RangeInclusive.html", &["begin</code>, <code>end"]),
     ("core/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
     ("alloc/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
     ("std/slice/trait.SliceIndex.html", &["begin</code>, <code>end"]),
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index dd5355134c5..25d559d789f 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-51917ba8f215f76e9d3fa8e77cd0a781bb28dab7
+51917e2e69702e5752bce6a4f3bfd285d0f4ae39
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index c9db798caad..71f6a2bc033 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -758,6 +758,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
 
+            "_Unwind_RaiseException" => {
+                // This is not formally part of POSIX, but it is very wide-spread on POSIX systems.
+                // It was originally specified as part of the Itanium C++ ABI:
+                // https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-throw.
+                // MinGW implements _Unwind_RaiseException on top of SEH exceptions.
+                if this.tcx.sess.target.env != "gnu" {
+                    throw_unsup_format!(
+                        "`_Unwind_RaiseException` is not supported on non-MinGW Windows",
+                    );
+                }
+                // This function looks and behaves excatly like miri_start_unwind.
+                let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?;
+                this.handle_miri_start_unwind(payload)?;
+                return Ok(EmulateItemResult::NeedsUnwind);
+            }
+
             _ => return Ok(EmulateItemResult::NotSupported),
         }
 
diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs
index ee651704c6f..c506c3d6b61 100644
--- a/src/tools/run-make-support/src/command.rs
+++ b/src/tools/run-make-support/src/command.rs
@@ -75,11 +75,12 @@ impl Command {
     /// Generic command arguments provider. Prefer specific helper methods if possible.
     /// Note that for some executables, arguments might be platform specific. For C/C++
     /// compilers, arguments might be platform *and* compiler specific.
-    pub fn args<S>(&mut self, args: &[S]) -> &mut Self
+    pub fn args<S, V>(&mut self, args: V) -> &mut Self
     where
         S: AsRef<ffi::OsStr>,
+        V: AsRef<[S]>,
     {
-        self.cmd.args(args);
+        self.cmd.args(args.as_ref());
         self
     }
 
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 9a180fe4ad1..7bb89106de1 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -261,6 +261,47 @@ pub fn test_while_readonly<P: AsRef<Path>, F: FnOnce() + std::panic::UnwindSafe>
     success.unwrap();
 }
 
+/// Browse the directory `path` non-recursively and return all files which respect the parameters
+/// outlined by `closure`.
+#[track_caller]
+pub fn shallow_find_files<P: AsRef<Path>, F: Fn(&PathBuf) -> bool>(
+    path: P,
+    filter: F,
+) -> Vec<PathBuf> {
+    let mut matching_files = Vec::new();
+    for entry in fs_wrapper::read_dir(path) {
+        let entry = entry.expect("failed to read directory entry.");
+        let path = entry.path();
+
+        if path.is_file() && filter(&path) {
+            matching_files.push(path);
+        }
+    }
+    matching_files
+}
+
+/// Returns true if the filename at `path` starts with `prefix`.
+pub fn has_prefix<P: AsRef<Path>>(path: P, prefix: &str) -> bool {
+    path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix))
+}
+
+/// Returns true if the filename at `path` has the extension `extension`.
+pub fn has_extension<P: AsRef<Path>>(path: P, extension: &str) -> bool {
+    path.as_ref().extension().is_some_and(|ext| ext == extension)
+}
+
+/// Returns true if the filename at `path` does not contain `expected`.
+pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
+    !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
+}
+
+/// Returns true if the filename at `path` is not in `expected`.
+pub fn filename_not_in_denylist<P: AsRef<Path>>(path: P, expected: &[String]) -> bool {
+    path.as_ref()
+        .file_name()
+        .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned()))
+}
+
 /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
 /// available on the platform!
 #[track_caller]
diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs
index 14238e2fed5..f16d814b9f0 100644
--- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs
+++ b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs
@@ -241,11 +241,3 @@ impl Parse for QueryGroup {
         Ok(QueryGroup { group_path })
     }
 }
-
-struct Nothing;
-
-impl Parse for Nothing {
-    fn parse(_input: ParseStream<'_>) -> syn::Result<Self> {
-        Ok(Nothing)
-    }
-}
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 2da4e476e90..ff98bd538db 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -46,7 +46,6 @@ run-make/fmt-write-bloat/Makefile
 run-make/foreign-double-unwind/Makefile
 run-make/foreign-exceptions/Makefile
 run-make/foreign-rust-exceptions/Makefile
-run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
 run-make/interdependent-c-libraries/Makefile
@@ -64,7 +63,6 @@ run-make/issue-33329/Makefile
 run-make/issue-35164/Makefile
 run-make/issue-36710/Makefile
 run-make/issue-37839/Makefile
-run-make/issue-40535/Makefile
 run-make/issue-47551/Makefile
 run-make/issue-69368/Makefile
 run-make/issue-83045/Makefile
@@ -102,9 +100,6 @@ run-make/no-alloc-shim/Makefile
 run-make/no-builtins-attribute/Makefile
 run-make/no-duplicate-libs/Makefile
 run-make/obey-crate-type-flag/Makefile
-run-make/optimization-remarks-dir-pgo/Makefile
-run-make/optimization-remarks-dir/Makefile
-run-make/output-type-permutations/Makefile
 run-make/panic-abort-eh_frame/Makefile
 run-make/pass-linker-flags-flavor/Makefile
 run-make/pass-linker-flags-from-dep/Makefile
@@ -113,13 +108,10 @@ run-make/pass-non-c-like-enum-to-c/Makefile
 run-make/pdb-buildinfo-cl-cmd/Makefile
 run-make/pgo-gen-lto/Makefile
 run-make/pgo-gen-no-imp-symbols/Makefile
-run-make/pgo-gen/Makefile
 run-make/pgo-indirect-call-promotion/Makefile
-run-make/pgo-use/Makefile
 run-make/pointer-auth-link-with-c/Makefile
 run-make/print-calling-conventions/Makefile
 run-make/print-target-list/Makefile
-run-make/profile/Makefile
 run-make/prune-link-args/Makefile
 run-make/raw-dylib-alt-calling-convention/Makefile
 run-make/raw-dylib-c/Makefile
@@ -136,7 +128,6 @@ run-make/return-non-c-like-enum-from-c/Makefile
 run-make/rlib-format-packed-bundled-libs-2/Makefile
 run-make/rlib-format-packed-bundled-libs-3/Makefile
 run-make/rlib-format-packed-bundled-libs/Makefile
-run-make/rmeta-preferred/Makefile
 run-make/rustc-macro-dep-files/Makefile
 run-make/sanitizer-cdylib-link/Makefile
 run-make/sanitizer-dylib-link/Makefile
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 3e84bf3c34b..e8dff2dc261 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -112,7 +112,7 @@ pub fn check(
             let file = entry.path();
             let filename = file.file_name().unwrap().to_string_lossy();
             let filen_underscore = filename.replace('-', "_").replace(".rs", "");
-            let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features);
+            let filename_gate = test_filen_gate(&filen_underscore, &mut features);
 
             for (i, line) in contents.lines().enumerate() {
                 let mut err = |msg: &str| {
@@ -128,7 +128,7 @@ pub fn check(
                 };
                 match features.get_mut(feature_name) {
                     Some(f) => {
-                        if filename_is_gate_test {
+                        if filename_gate == Some(feature_name) {
                             err(&format!(
                                 "The file is already marked as gate test \
                                       through its name, no need for a \
@@ -259,18 +259,18 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
     r.captures(line).and_then(|c| c.get(1)).map(|m| m.as_str())
 }
 
-fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
+fn test_filen_gate<'f>(filen_underscore: &'f str, features: &mut Features) -> Option<&'f str> {
     let prefix = "feature_gate_";
-    if filen_underscore.starts_with(prefix) {
+    if let Some(suffix) = filen_underscore.strip_prefix(prefix) {
         for (n, f) in features.iter_mut() {
             // Equivalent to filen_underscore == format!("feature_gate_{n}")
-            if &filen_underscore[prefix.len()..] == n {
+            if suffix == n {
                 f.has_gate_test = true;
-                return true;
+                return Some(suffix);
             }
         }
     }
-    false
+    None
 }
 
 pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features {
diff --git a/tests/crashes/126896.rs b/tests/crashes/126896.rs
new file mode 100644
index 00000000000..35bf9d5207a
--- /dev/null
+++ b/tests/crashes/126896.rs
@@ -0,0 +1,17 @@
+//@ known-bug: rust-lang/rust#126896
+//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes
+
+#![feature(type_alias_impl_trait)]
+type Two<'a, 'b> = impl std::fmt::Debug;
+
+fn set(x: &mut isize) -> isize {
+    *x
+}
+
+fn d(x: Two) {
+    let c1 = || set(x);
+    c1;
+}
+
+fn main() {
+}
diff --git a/tests/crashes/126939.rs b/tests/crashes/126939.rs
new file mode 100644
index 00000000000..1edf7484606
--- /dev/null
+++ b/tests/crashes/126939.rs
@@ -0,0 +1,21 @@
+//@ known-bug: rust-lang/rust#126939
+
+struct MySlice<T: Copy>(bool, T);
+type MySliceBool = MySlice<[bool]>;
+
+use std::mem;
+
+struct P2<T> {
+    a: T,
+    b: MySliceBool,
+}
+
+macro_rules! check {
+    ($t:ty, $align:expr) => ({
+        assert_eq!(mem::align_of::<$t>(), $align);
+    });
+}
+
+pub fn main() {
+    check!(P2<u8>, 1);
+}
diff --git a/tests/crashes/126942.rs b/tests/crashes/126942.rs
new file mode 100644
index 00000000000..e4adc8fab28
--- /dev/null
+++ b/tests/crashes/126942.rs
@@ -0,0 +1,11 @@
+//@ known-bug: rust-lang/rust#126942
+struct Thing;
+
+pub trait Every {
+    type Assoc;
+}
+impl<T: ?Sized> Every for Thing {
+    type Assoc = T;
+}
+
+static I: <Thing as Every>::Assoc = 3;
diff --git a/tests/crashes/126944.rs b/tests/crashes/126944.rs
new file mode 100644
index 00000000000..c0c5622e260
--- /dev/null
+++ b/tests/crashes/126944.rs
@@ -0,0 +1,38 @@
+//@ known-bug: rust-lang/rust#126944
+// Step 1: Create two names for a single type: `Thing` and `AlsoThing`
+
+struct Thing;
+struct Dummy;
+pub trait DummyTrait {
+    type DummyType;
+}
+impl DummyTrait for Dummy {
+    type DummyType = Thing;
+}
+type AlsoThing = <Dummy as DummyTrait>::DummyType;
+
+// Step 2: Create names for a single trait object type: `TraitObject` and `AlsoTraitObject`
+
+pub trait SomeTrait {
+    type Item;
+}
+type TraitObject = dyn SomeTrait<Item = AlsoThing>;
+type AlsoTraitObject = dyn SomeTrait<Item = Thing>;
+
+// Step 3: Force the compiler to check whether the two names are the same type
+
+pub trait Supertrait {
+    type Foo;
+}
+pub trait Subtrait: Supertrait<Foo = TraitObject> {}
+
+pub trait HasOutput<A: ?Sized> {
+    type Output;
+}
+
+fn foo<F>() -> F::Output
+where
+    F: HasOutput<dyn Subtrait<Foo = AlsoTraitObject>>,
+{
+    todo!()
+}
diff --git a/tests/crashes/126966.rs b/tests/crashes/126966.rs
new file mode 100644
index 00000000000..edeedc68c40
--- /dev/null
+++ b/tests/crashes/126966.rs
@@ -0,0 +1,29 @@
+//@ known-bug: rust-lang/rust#126966
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src>,
+    {
+    }
+}
+
+#[repr(u32)]
+enum Ox00 {
+    V = 0x00,
+}
+
+#[repr(C, packed(2))]
+enum OxFF {
+    V = 0xFF,
+}
+
+fn test() {
+    union Superset {
+        a: Ox00,
+        b: OxFF,
+    }
+
+    assert::is_transmutable::<Superset, Subset>();
+}
diff --git a/tests/crashes/126969.rs b/tests/crashes/126969.rs
new file mode 100644
index 00000000000..676563d059c
--- /dev/null
+++ b/tests/crashes/126969.rs
@@ -0,0 +1,9 @@
+//@ known-bug: rust-lang/rust#126969
+
+struct S<T> {
+    _: union { t: T },
+}
+
+fn f(S::<&i8> { .. }: S<&i8>) {}
+
+fn main() {}
diff --git a/tests/crashes/126982.rs b/tests/crashes/126982.rs
new file mode 100644
index 00000000000..8522d9415eb
--- /dev/null
+++ b/tests/crashes/126982.rs
@@ -0,0 +1,18 @@
+//@ known-bug: rust-lang/rust#126982
+
+#![feature(coerce_unsized)]
+use std::ops::CoerceUnsized;
+
+struct Foo<T: ?Sized> {
+    a: T,
+}
+
+impl<T, U> CoerceUnsized<U> for Foo<T> {}
+
+union U {
+    a: usize,
+}
+
+const C: U = Foo { a: 10 };
+
+fn main() {}
diff --git a/tests/crashes/127222.rs b/tests/crashes/127222.rs
new file mode 100644
index 00000000000..eda0ea3d9b7
--- /dev/null
+++ b/tests/crashes/127222.rs
@@ -0,0 +1,3 @@
+//@ known-bug: rust-lang/rust#127222
+#[marker]
+trait Foo = PartialEq<i32> + Send;
diff --git a/tests/crashes/127266.rs b/tests/crashes/127266.rs
new file mode 100644
index 00000000000..2bdbe03e373
--- /dev/null
+++ b/tests/crashes/127266.rs
@@ -0,0 +1,17 @@
+//@ known-bug: rust-lang/rust#127266
+#![feature(const_mut_refs)]
+#![feature(const_refs_to_static)]
+
+struct Meh {
+    x: &'static dyn UnsafeCell,
+}
+
+const MUH: Meh = Meh {
+    x: &mut *(READONLY as *mut _),
+};
+
+static READONLY: i32 = 0;
+
+trait UnsafeCell<'a> {}
+
+pub fn main() {}
diff --git a/tests/crashes/127299.rs b/tests/crashes/127299.rs
new file mode 100644
index 00000000000..7eb78387997
--- /dev/null
+++ b/tests/crashes/127299.rs
@@ -0,0 +1,12 @@
+//@ known-bug: rust-lang/rust#127299
+trait Qux {
+    fn bar() -> i32;
+}
+
+pub struct Lint {
+    pub desc: &'static Qux,
+}
+
+static FOO: &Lint = &Lint { desc: "desc" };
+
+fn main() {}
diff --git a/tests/crashes/127304.rs b/tests/crashes/127304.rs
new file mode 100644
index 00000000000..2975fc27f67
--- /dev/null
+++ b/tests/crashes/127304.rs
@@ -0,0 +1,20 @@
+//@ known-bug: rust-lang/rust #127304
+#![feature(adt_const_params)]
+
+trait Trait<T> {}
+impl Trait<u16> for () {}
+
+struct MyStr(str);
+impl std::marker::ConstParamTy for MyStr {}
+
+fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
+    S
+}
+
+impl MyStr {
+    const fn new(s: &Trait str) -> &'static MyStr {}
+}
+
+pub fn main() {
+    let f = function_with_my_str::<{ MyStr::new("hello") }>();
+}
diff --git a/tests/crashes/127332.rs b/tests/crashes/127332.rs
new file mode 100644
index 00000000000..5c14af01cec
--- /dev/null
+++ b/tests/crashes/127332.rs
@@ -0,0 +1,9 @@
+//@ known-bug: rust-lang/rust #127332
+
+async fn fun() {
+    enum Foo {
+        A { x: u32 },
+    }
+    let orig = Foo::A { x: 5 };
+    Foo::A { x: 6, ..orig };
+}
diff --git a/tests/run-make/include_bytes_deps/input.bin b/tests/run-make/include-bytes-deps/input.bin
index cd0875583aa..cd0875583aa 100644
--- a/tests/run-make/include_bytes_deps/input.bin
+++ b/tests/run-make/include-bytes-deps/input.bin
diff --git a/tests/run-make/include_bytes_deps/input.md b/tests/run-make/include-bytes-deps/input.md
index 2a19b7405f7..2a19b7405f7 100644
--- a/tests/run-make/include_bytes_deps/input.md
+++ b/tests/run-make/include-bytes-deps/input.md
diff --git a/tests/run-make/include_bytes_deps/input.txt b/tests/run-make/include-bytes-deps/input.txt
index cd0875583aa..cd0875583aa 100644
--- a/tests/run-make/include_bytes_deps/input.txt
+++ b/tests/run-make/include-bytes-deps/input.txt
diff --git a/tests/run-make/include_bytes_deps/main.rs b/tests/run-make/include-bytes-deps/main.rs
index 2fd55699d44..2fd55699d44 100644
--- a/tests/run-make/include_bytes_deps/main.rs
+++ b/tests/run-make/include-bytes-deps/main.rs
diff --git a/tests/run-make/include-bytes-deps/rmake.rs b/tests/run-make/include-bytes-deps/rmake.rs
new file mode 100644
index 00000000000..ea371ddae56
--- /dev/null
+++ b/tests/run-make/include-bytes-deps/rmake.rs
@@ -0,0 +1,13 @@
+// include_bytes! and include_str! in `main.rs`
+// should register the included file as of #24423,
+// and this test checks that this is still the case.
+// See https://github.com/rust-lang/rust/pull/24423
+
+use run_make_support::{invalid_utf8_contains, rustc};
+
+fn main() {
+    rustc().emit("dep-info").input("main.rs").run();
+    invalid_utf8_contains("main.d", "input.txt");
+    invalid_utf8_contains("main.d", "input.bin");
+    invalid_utf8_contains("main.d", "input.md");
+}
diff --git a/tests/run-make/include_bytes_deps/Makefile b/tests/run-make/include_bytes_deps/Makefile
deleted file mode 100644
index 696dfd207bb..00000000000
--- a/tests/run-make/include_bytes_deps/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../tools.mk
-
-# ignore-freebsd
-
-all:
-	$(RUSTC) --emit dep-info main.rs
-	$(CGREP) "input.txt" "input.bin" "input.md" < $(TMPDIR)/main.d
diff --git a/tests/run-make/issue-40535/Makefile b/tests/run-make/issue-40535/Makefile
deleted file mode 100644
index 155c8825214..00000000000
--- a/tests/run-make/issue-40535/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-include ../tools.mk
-
-# The ICE occurred in the following situation:
-# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`)
-# * `bar` declares and depends on `extern crate baz`
-# * All crates built in metadata-only mode (`cargo check`)
-all:
-	# cc https://github.com/rust-lang/rust/issues/40623
-	$(RUSTC) baz.rs --emit=metadata
-	$(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta
-	$(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta 2>&1 | \
-		$(CGREP) -v "unexpectedly panicked"
-	# ^ Succeeds if it doesn't find the ICE message
diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs
index f460829288e..6934a4b36d0 100644
--- a/tests/run-make/llvm-ident/rmake.rs
+++ b/tests/run-make/llvm-ident/rmake.rs
@@ -28,7 +28,7 @@ fn main() {
             files.push(path.to_path_buf());
         }
     });
-    cmd(llvm_bin_dir().join("llvm-dis")).args(&files).run();
+    cmd(llvm_bin_dir().join("llvm-dis")).args(files).run();
 
     // Check LLVM IR files (including temporary outputs) have `!llvm.ident`
     // named metadata, reusing the related codegen test.
diff --git a/tests/run-make/issue-40535/bar.rs b/tests/run-make/metadata-only-crate-no-ice/bar.rs
index b02b28f59d9..b02b28f59d9 100644
--- a/tests/run-make/issue-40535/bar.rs
+++ b/tests/run-make/metadata-only-crate-no-ice/bar.rs
diff --git a/tests/run-make/issue-40535/baz.rs b/tests/run-make/metadata-only-crate-no-ice/baz.rs
index 83be6e807e0..83be6e807e0 100644
--- a/tests/run-make/issue-40535/baz.rs
+++ b/tests/run-make/metadata-only-crate-no-ice/baz.rs
diff --git a/tests/run-make/issue-40535/foo.rs b/tests/run-make/metadata-only-crate-no-ice/foo.rs
index 27020266425..27020266425 100644
--- a/tests/run-make/issue-40535/foo.rs
+++ b/tests/run-make/metadata-only-crate-no-ice/foo.rs
diff --git a/tests/run-make/metadata-only-crate-no-ice/rmake.rs b/tests/run-make/metadata-only-crate-no-ice/rmake.rs
new file mode 100644
index 00000000000..e6f852fca41
--- /dev/null
+++ b/tests/run-make/metadata-only-crate-no-ice/rmake.rs
@@ -0,0 +1,14 @@
+// In a dependency hierarchy, metadata-only crates could cause an Internal
+// Compiler Error (ICE) due to a compiler bug - not correctly fetching sources for
+// metadata-only crates. This test is a minimal reproduction of a program that triggered
+// this bug, and checks that no ICE occurs.
+// See https://github.com/rust-lang/rust/issues/40535
+
+use run_make_support::rustc;
+
+fn main() {
+    rustc().input("baz.rs").emit("metadata").run();
+    rustc().input("bar.rs").emit("metadata").extern_("baz", "libbaz.rmeta").run();
+    // There should be no internal compiler error.
+    rustc().input("foo.rs").emit("metadata").extern_("bar", "libbaz.rmeta").run();
+}
diff --git a/tests/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile
deleted file mode 100644
index 57ffd6e70f0..00000000000
--- a/tests/run-make/optimization-remarks-dir-pgo/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# needs-profiler-support
-# ignore-cross-compile
-
-include ../tools.mk
-
-PROFILE_DIR=$(TMPDIR)/profiles
-
-check_hotness:
-	$(RUSTC) -Cprofile-generate="$(TMPDIR)"/profdata -O foo.rs -o$(TMPDIR)/foo
-	$(TMPDIR)/foo
-	"$(LLVM_BIN_DIR)"/llvm-profdata merge \
-		-o "$(TMPDIR)"/merged.profdata \
-		"$(TMPDIR)"/profdata/*.profraw
-	$(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata -O foo.rs -Cremark=all -Zremark-dir=$(PROFILE_DIR)
-
-	# Check that PGO hotness is included in the remark files
-	cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "Hotness"
diff --git a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs
new file mode 100644
index 00000000000..228c43cc5f1
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs
@@ -0,0 +1,41 @@
+// This test checks the -Zremark-dir flag, which writes LLVM
+// optimization remarks to the YAML format. When using PGO (Profile
+// Guided Optimization), the Hotness attribute should be included in
+// the output remark files.
+// See https://github.com/rust-lang/rust/pull/114439
+
+//@ needs-profiler-support
+//@ ignore-cross-compile
+
+use run_make_support::{
+    has_extension, has_prefix, invalid_utf8_contains, llvm_profdata, run, rustc, shallow_find_files,
+};
+
+fn main() {
+    rustc().profile_generate("profdata").opt().input("foo.rs").output("foo").run();
+    run("foo");
+    // The profdata filename is a long sequence of numbers, fetch it by prefix and extension
+    // to keep the test working even if the filename changes.
+    let profdata_files = shallow_find_files("profdata", |path| {
+        has_prefix(path, "default") && has_extension(path, "profraw")
+    });
+    let profdata_file = profdata_files.get(0).unwrap();
+    llvm_profdata().merge().output("merged.profdata").input(profdata_file).run();
+    rustc()
+        .profile_use("merged.profdata")
+        .opt()
+        .input("foo.rs")
+        .arg("-Cremark=all")
+        .arg("-Zremark-dir=profiles")
+        .run();
+    // Check that PGO hotness is included in the remark files
+    let remark_files = shallow_find_files("profiles", |path| {
+        has_prefix(path, "foo") && has_extension(path, "yaml")
+    });
+    assert!(!remark_files.is_empty());
+    for file in remark_files {
+        if !file.to_str().unwrap().contains("codegen") {
+            invalid_utf8_contains(file, "Hotness")
+        };
+    }
+}
diff --git a/tests/run-make/optimization-remarks-dir/Makefile b/tests/run-make/optimization-remarks-dir/Makefile
deleted file mode 100644
index a8342c8ad14..00000000000
--- a/tests/run-make/optimization-remarks-dir/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-include ../tools.mk
-
-PROFILE_DIR=$(TMPDIR)/profiles
-
-all: check_inline check_filter
-
-check_inline:
-	$(RUSTC) -O foo.rs --crate-type=lib -Cremark=all -Zremark-dir=$(PROFILE_DIR)
-	cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "inline"
-check_filter:
-	$(RUSTC) -O foo.rs --crate-type=lib -Cremark=foo -Zremark-dir=$(PROFILE_DIR)
-	cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e -v "inline"
diff --git a/tests/run-make/optimization-remarks-dir/rmake.rs b/tests/run-make/optimization-remarks-dir/rmake.rs
new file mode 100644
index 00000000000..afcb8c3e3eb
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir/rmake.rs
@@ -0,0 +1,39 @@
+// In this test, the function `bar` has #[inline(never)] and the function `foo`
+// does not. This test outputs LLVM optimization remarks twice - first for all
+// functions (including `bar`, and the `inline` mention), and then for only `foo`
+// (should not have the `inline` mention).
+// See https://github.com/rust-lang/rust/pull/113040
+
+use run_make_support::{
+    has_extension, has_prefix, invalid_utf8_contains, invalid_utf8_not_contains, not_contains,
+    rustc, shallow_find_files,
+};
+
+fn main() {
+    rustc()
+        .opt()
+        .input("foo.rs")
+        .crate_type("lib")
+        .arg("-Cremark=all")
+        .arg("-Zremark-dir=profiles_all")
+        .run();
+    let all_remark_files = shallow_find_files("profiles_all", |path| {
+        has_prefix(path, "foo") && has_extension(path, "yaml") && not_contains(path, "codegen")
+    });
+    for file in all_remark_files {
+        invalid_utf8_contains(file, "inline")
+    }
+    rustc()
+        .opt()
+        .input("foo.rs")
+        .crate_type("lib")
+        .arg("-Cremark=foo")
+        .arg("-Zremark-dir=profiles_foo")
+        .run();
+    let foo_remark_files = shallow_find_files("profiles_foo", |path| {
+        has_prefix(path, "foo") && has_extension(path, "yaml")
+    });
+    for file in foo_remark_files {
+        invalid_utf8_not_contains(file, "inline")
+    }
+}
diff --git a/tests/run-make/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile
deleted file mode 100644
index 035033b9fdd..00000000000
--- a/tests/run-make/output-type-permutations/Makefile
+++ /dev/null
@@ -1,147 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib
-	$(call REMOVE_RLIBS,bar)
-	$(call REMOVE_DYLIBS,bar)
-	rm $(call STATICLIB,bar)
-	rm -f $(TMPDIR)/{lib,}bar.{dll.exp,dll.lib,pdb,dll.a}
-	# Check that $(TMPDIR) is empty.
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=bin
-	rm $(TMPDIR)/$(call BIN,bar)
-	rm -f $(TMPDIR)/bar.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link
-	rm $(TMPDIR)/bar.ll
-	rm $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/bar.s
-	rm $(TMPDIR)/bar.o
-	rm $(TMPDIR)/$(call BIN,bar)
-	rm -f $(TMPDIR)/bar.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=asm=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=llvm-bc=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=llvm-ir=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --emit=obj=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/foo.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=rlib --emit=link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=dylib --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/{lib,}foo.{dll.exp,dll.lib,pdb,dll.a,exe.a}
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] || (ls -1 $(TMPDIR) && exit 1)
-
-	$(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	$(RUSTC) foo.rs --crate-type=staticlib --emit=link=$(TMPDIR)/foo
-	rm $(TMPDIR)/foo
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	$(RUSTC) foo.rs --crate-type=bin --emit=link=$(TMPDIR)/$(call BIN,foo)
-	rm $(TMPDIR)/$(call BIN,foo)
-	rm -f $(TMPDIR)/foo.pdb
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \
-			--emit link \
-			--crate-type=rlib
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/libbar.rlib
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \
-			--emit llvm-ir=$(TMPDIR)/ir \
-			--emit llvm-bc=$(TMPDIR)/bc \
-		        --emit obj=$(TMPDIR)/obj \
-			--emit link=$(TMPDIR)/link \
-			--crate-type=staticlib
-	rm $(TMPDIR)/asm
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/bc
-	rm $(TMPDIR)/obj
-	rm $(TMPDIR)/link
-	$(RUSTC) foo.rs --emit=asm=$(TMPDIR)/asm \
-			--emit llvm-ir=$(TMPDIR)/ir \
-			--emit=llvm-bc=$(TMPDIR)/bc \
-		        --emit obj=$(TMPDIR)/obj \
-			--emit=link=$(TMPDIR)/link \
-			--crate-type=staticlib
-	rm $(TMPDIR)/asm
-	rm $(TMPDIR)/ir
-	rm $(TMPDIR)/bc
-	rm $(TMPDIR)/obj
-	rm $(TMPDIR)/link
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
-
-	$(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib
-	rm $(TMPDIR)/bar.ll
-	rm $(TMPDIR)/bar.s
-	rm $(TMPDIR)/bar.o
-	rm $(call STATICLIB,bar)
-	mv $(TMPDIR)/bar.bc $(TMPDIR)/foo.bc
-	# Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later
-	# comparison.
-
-	$(RUSTC) foo.rs --emit=llvm-bc,link --crate-type=rlib
-	cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/bar.bc
-	rm $(TMPDIR)/foo.bc
-	$(call REMOVE_RLIBS,bar)
-	[ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ]
diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs
new file mode 100644
index 00000000000..30036dc7eea
--- /dev/null
+++ b/tests/run-make/output-type-permutations/rmake.rs
@@ -0,0 +1,543 @@
+// In 2014, rustc's output flags were reworked to be a lot more modular.
+// This test uses these output flags in an expansive variety of combinations
+// and syntax styles, checking that compilation is successful and that output
+// files are exactly what is expected, no more, no less.
+// See https://github.com/rust-lang/rust/pull/12020
+
+use run_make_support::{
+    bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc,
+    shallow_find_files, static_lib_name,
+};
+use std::path::PathBuf;
+
+// Each test takes 4 arguments:
+// `must_exist`: output files which must be found - if any are absent, the test fails
+// `can_exist`: optional output files which will not trigger a failure
+// `dir`: the name of the directory where the test happens
+// `rustc_invocation`: the rustc command being tested
+// Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure.
+fn assert_expected_output_files(expectations: Expectations, rustc_invocation: impl Fn()) {
+    let must_exist = expectations.expected_files;
+    let can_exist = expectations.allowed_files;
+    let dir = expectations.test_dir;
+
+    fs_wrapper::create_dir(&dir);
+    rustc_invocation();
+    for file in must_exist {
+        fs_wrapper::remove_file(PathBuf::from(&dir).join(&file));
+    }
+    let actual_output_files =
+        shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist));
+    if !&actual_output_files.is_empty() {
+        dbg!(&actual_output_files);
+        panic!("unexpected output artifacts detected");
+    }
+}
+
+struct Expectations {
+    /// Output files which must be found. The test fails if any are absent.
+    expected_files: Vec<String>,
+    /// Allowed output files which will not trigger a failure.
+    allowed_files: Vec<String>,
+    /// Name of the directory where the test happens.
+    test_dir: String,
+}
+
+macro_rules! s {
+    ( $( $x:expr ),* ) => {
+        {
+            let mut temp_vec = Vec::new();
+            $(
+                temp_vec.push($x.to_string());
+            )*
+            temp_vec
+        }
+    };
+}
+
+fn main() {
+    let bin_foo = bin_name("foo");
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![
+                static_lib_name("bar"),
+                dynamic_lib_name("bar"),
+                rust_lib_name("bar")
+            ],
+            allowed_files: s![
+                "libbar.dll.exp",
+                "libbar.dll.lib",
+                "libbar.pdb",
+                "libbar.dll.a",
+                "libbar.exe.a",
+                "bar.dll.exp",
+                "bar.dll.lib",
+                "bar.pdb",
+                "bar.dll.a",
+                "bar.exe.a"
+            ],
+            test_dir: "three-crates".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .out_dir("three-crates")
+                .crate_type("rlib,dylib,staticlib")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_name("bar")],
+            allowed_files: s!["bar.pdb"],
+            test_dir: "bin-crate".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.ll", "bar.bc", "bar.s", "bar.o", bin_name("bar")],
+            allowed_files: s!["bar.pdb"],
+            test_dir: "all-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").out_dir("all-emit").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("asm=asm-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "asm-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-ir-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "llvm-bc-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("obj=obj-emit2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "obj-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + &bin_foo).run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit2".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![&bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "link-emit3".to_string(),
+        },
+        || {
+            rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib2".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "rlib3".to_string(),
+        },
+        || {
+            rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .output("dylib/".to_owned() + &bin_foo)
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib2".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .emit(&format!("link=dylib2/{bin_foo}"))
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s![
+                "libfoo.dll.exp",
+                "libfoo.dll.lib",
+                "libfoo.pdb",
+                "libfoo.dll.a",
+                "libfoo.exe.a",
+                "foo.dll.exp",
+                "foo.dll.lib",
+                "foo.pdb",
+                "foo.dll.a",
+                "foo.exe.a"
+            ],
+            test_dir: "dylib3".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("dylib")
+                .input("foo.rs")
+                .arg(&format!("--emit=link=dylib3/{bin_foo}"))
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib2".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["foo"],
+            allowed_files: s![],
+            test_dir: "staticlib3".to_string(),
+        },
+        || {
+            rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .output("bincrate/".to_owned() + &bin_foo)
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate2".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .emit(&format!("link=bincrate2/{bin_foo}"))
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s![bin_foo],
+            allowed_files: s!["foo.pdb"],
+            test_dir: "bincrate3".to_string(),
+        },
+        || {
+            rustc()
+                .crate_type("bin")
+                .input("foo.rs")
+                .arg(&format!("--emit=link=bincrate3/{bin_foo}"))
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", rust_lib_name("bar")],
+            allowed_files: s![],
+            test_dir: "rlib-ir".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("llvm-ir=rlib-ir/ir")
+                .emit("link")
+                .crate_type("rlib")
+                .out_dir("rlib-ir")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", "asm", "bc", "obj", "link"],
+            allowed_files: s![],
+            test_dir: "staticlib-all".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("asm=staticlib-all/asm")
+                .emit("llvm-ir=staticlib-all/ir")
+                .emit("llvm-bc=staticlib-all/bc")
+                .emit("obj=staticlib-all/obj")
+                .emit("link=staticlib-all/link")
+                .crate_type("staticlib")
+                .run();
+        },
+    );
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["ir", "asm", "bc", "obj", "link"],
+            allowed_files: s![],
+            test_dir: "staticlib-all2".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .arg("--emit=asm=staticlib-all2/asm")
+                .arg("--emit")
+                .arg("llvm-ir=staticlib-all2/ir")
+                .arg("--emit=llvm-bc=staticlib-all2/bc")
+                .arg("--emit")
+                .arg("obj=staticlib-all2/obj")
+                .arg("--emit=link=staticlib-all2/link")
+                .crate_type("staticlib")
+                .run();
+        },
+    );
+
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.ll", "bar.s", "bar.o", static_lib_name("bar")],
+            allowed_files: s!["bar.bc"], // keep this one for the next test
+            test_dir: "staticlib-all3".to_string(),
+        },
+        || {
+            rustc()
+                .input("foo.rs")
+                .emit("asm,llvm-ir,llvm-bc,obj,link")
+                .crate_type("staticlib")
+                .out_dir("staticlib-all3")
+                .run();
+        },
+    );
+
+    // the .bc file from the previous test should be equivalent to this one, despite the difference
+    // in crate type
+    assert_expected_output_files(
+        Expectations {
+            expected_files: s!["bar.bc", rust_lib_name("bar"), "foo.bc"],
+            allowed_files: s![],
+            test_dir: "rlib-emits".to_string(),
+        },
+        || {
+            fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc");
+            rustc()
+                .input("foo.rs")
+                .emit("llvm-bc,link")
+                .crate_type("rlib")
+                .out_dir("rlib-emits")
+                .run();
+            assert_eq!(
+                fs_wrapper::read("rlib-emits/foo.bc"),
+                fs_wrapper::read("rlib-emits/bar.bc")
+            );
+        },
+    );
+}
diff --git a/tests/run-make/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile
deleted file mode 100644
index c1d456986fb..00000000000
--- a/tests/run-make/pgo-gen/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# needs-profiler-support
-# ignore-cross-compile
-
-include ../tools.mk
-
-COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)"
-
-all:
-	$(RUSTC) $(COMPILE_FLAGS) test.rs
-	$(call RUN,test) || exit 1
-	[ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1)
diff --git a/tests/run-make/pgo-gen/rmake.rs b/tests/run-make/pgo-gen/rmake.rs
new file mode 100644
index 00000000000..ad2f6388e8f
--- /dev/null
+++ b/tests/run-make/pgo-gen/rmake.rs
@@ -0,0 +1,18 @@
+// -C profile-generate, when used with rustc, is supposed to output
+// profile files (.profraw) after running a binary to analyze how the compiler
+// optimizes code. This test checks that these files are generated.
+// See https://github.com/rust-lang/rust/pull/48346
+
+//@ needs-profiler-support
+//@ ignore-cross-compile
+
+use run_make_support::{cwd, has_extension, has_prefix, run, rustc, shallow_find_files};
+
+fn main() {
+    rustc().arg("-g").profile_generate(cwd()).input("test.rs").run();
+    run("test");
+    let profraw_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "default") && has_extension(path, "profraw")
+    });
+    assert!(!profraw_files.is_empty(), "no .profraw file generated");
+}
diff --git a/tests/run-make/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile
deleted file mode 100644
index 92098a4019c..00000000000
--- a/tests/run-make/pgo-use/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# needs-profiler-support
-# ignore-cross-compile
-
-include ../tools.mk
-
-# This test makes sure that PGO profiling data leads to cold functions being
-# marked as `cold` and hot functions with `inlinehint`.
-# The test program contains an `if` were actual execution only ever takes the
-# `else` branch. Accordingly, we expect the function that is never called to
-# be marked as cold.
-#
-# Disable the pre-inlining pass (i.e. a pass that does some inlining before
-# it adds the profiling instrumentation). Disabling this pass leads to
-# rather predictable IR which we need for this test to be stable.
-
-COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline
-
-ifeq ($(UNAME),Darwin)
-# macOS does not have the `tac` command, but `tail -r` does the same thing
-TAC := tail -r
-else
-# some other platforms don't support the `-r` flag for `tail`, so use `tac`
-TAC := tac
-endif
-
-all:
-	# Compile the test program with instrumentation
-	$(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs
-	# Run it in order to generate some profiling data
-	$(call RUN,main some-argument) || exit 1
-	# Postprocess the profiling data so it can be used by the compiler
-	"$(LLVM_BIN_DIR)"/llvm-profdata merge \
-		-o "$(TMPDIR)"/merged.profdata \
-		"$(TMPDIR)"/default_*.profraw
-	# Compile the test program again, making use of the profiling data
-	$(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs
-	# Check that the generate IR contains some things that we expect
-	#
-	# We feed the file into LLVM FileCheck tool *in reverse* so that we see the
-	# line with the function name before the line with the function attributes.
-	# FileCheck only supports checking that something matches on the next line,
-	# but not if something matches on the previous line.
-	$(TAC) "$(TMPDIR)"/main.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt
diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs
new file mode 100644
index 00000000000..0f76aff80d0
--- /dev/null
+++ b/tests/run-make/pgo-use/rmake.rs
@@ -0,0 +1,55 @@
+// This test makes sure that PGO profiling data leads to cold functions being
+// marked as `cold` and hot functions with `inlinehint`.
+// The test program contains an `if` where actual execution only ever takes the
+// `else` branch. Accordingly, we expect the function that is never called to
+// be marked as cold.
+// See https://github.com/rust-lang/rust/pull/60262
+
+//@ needs-profiler-support
+//@ ignore-cross-compile
+
+use run_make_support::{
+    cwd, fs_wrapper, has_extension, has_prefix, llvm_filecheck, llvm_profdata, run_with_args,
+    rustc, shallow_find_files,
+};
+
+fn main() {
+    // Compile the test program with instrumentation
+    // Disable the pre-inlining pass (i.e. a pass that does some inlining before
+    // it adds the profiling instrumentation). Disabling this pass leads to
+    // rather predictable IR which we need for this test to be stable.
+    rustc()
+        .opt_level("2")
+        .codegen_units(1)
+        .arg("-Cllvm-args=-disable-preinline")
+        .profile_generate(cwd())
+        .input("main.rs")
+        .run();
+    // Run it in order to generate some profiling data
+    run_with_args("main", &["some-argument"]);
+    // Postprocess the profiling data so it can be used by the compiler
+    let profraw_files = shallow_find_files(cwd(), |path| {
+        has_prefix(path, "default") && has_extension(path, "profraw")
+    });
+    let profraw_file = profraw_files.get(0).unwrap();
+    llvm_profdata().merge().output("merged.profdata").input(profraw_file).run();
+    // Compile the test program again, making use of the profiling data
+    rustc()
+        .opt_level("2")
+        .codegen_units(1)
+        .arg("-Cllvm-args=-disable-preinline")
+        .profile_use("merged.profdata")
+        .emit("llvm-ir")
+        .input("main.rs")
+        .run();
+    // Check that the generate IR contains some things that we expect.
+    // We feed the file into LLVM FileCheck tool *with its lines reversed* so that we see the
+    // line with the function name before the line with the function attributes.
+    // FileCheck only supports checking that something matches on the next line,
+    // but not if something matches on the previous line.
+    let ir = fs_wrapper::read_to_string("main.ll");
+    let lines: Vec<_> = ir.lines().rev().collect();
+    let mut reversed_ir = lines.join("\n");
+    reversed_ir.push('\n');
+    llvm_filecheck().patterns("filecheck-patterns.txt").stdin(reversed_ir.as_bytes()).run();
+}
diff --git a/tests/run-make/profile/Makefile b/tests/run-make/profile/Makefile
deleted file mode 100644
index 7919b18ba74..00000000000
--- a/tests/run-make/profile/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# needs-profiler-support
-# ignore-cross-compile
-
-include ../tools.mk
-
-all:
-	$(RUSTC) -g -Z profile test.rs
-	$(call RUN,test) || exit 1
-	[ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1)
-	[ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1)
-	$(RUSTC) -g -Z profile -Z profile-emit=$(TMPDIR)/abc/abc.gcda test.rs
-	$(call RUN,test) || exit 1
-	[ -e "$(TMPDIR)/abc/abc.gcda" ] || (echo "gcda file not emitted to defined path"; exit 1)
diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs
new file mode 100644
index 00000000000..8d41978baec
--- /dev/null
+++ b/tests/run-make/profile/rmake.rs
@@ -0,0 +1,22 @@
+// This test revolves around the rustc flag -Z profile, which should
+// generate a .gcno file (initial profiling information) as well
+// as a .gcda file (branch counters). The path where these are emitted
+// should also be configurable with -Z profile-emit. This test checks
+// that the files are produced, and then that the latter flag is respected.
+// See https://github.com/rust-lang/rust/pull/42433
+
+//@ ignore-cross-compile
+//@ needs-profiler-support
+
+use run_make_support::{run, rustc};
+use std::path::Path;
+
+fn main() {
+    rustc().arg("-g").arg("-Zprofile").input("test.rs").run();
+    run("test");
+    assert!(Path::new("test.gcno").exists(), "no .gcno file");
+    assert!(Path::new("test.gcda").exists(), "no .gcda file");
+    rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run();
+    run("test");
+    assert!(Path::new("abc/abc.gcda").exists(), "gcda file not emitted to defined path");
+}
diff --git a/tests/run-make/rmeta-preferred/Makefile b/tests/run-make/rmeta-preferred/Makefile
deleted file mode 100644
index 3bf12cced29..00000000000
--- a/tests/run-make/rmeta-preferred/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# Test that using rlibs and rmeta dep crates work together. Specifically, that
-# there can be both an rmeta and an rlib file and rustc will prefer the rmeta
-# file.
-#
-# This behavior is simply making sure this doesn't accidentally change; in this
-# case we want to make sure that the rlib isn't being used as that would cause
-# bugs in -Zbinary-dep-depinfo (see #68298).
-
-all:
-	$(RUSTC) rmeta_aux.rs --crate-type=rlib --emit link,metadata
-	$(RUSTC) lib.rs --crate-type=rlib --emit dep-info -Zbinary-dep-depinfo
-	$(CGREP) "librmeta_aux.rmeta" < $(TMPDIR)/lib.d
-	$(CGREP) -v "librmeta_aux.rlib" < $(TMPDIR)/lib.d
diff --git a/tests/run-make/rmeta-preferred/rmake.rs b/tests/run-make/rmeta-preferred/rmake.rs
new file mode 100644
index 00000000000..09cba06e2f5
--- /dev/null
+++ b/tests/run-make/rmeta-preferred/rmake.rs
@@ -0,0 +1,18 @@
+// This test compiles `lib.rs`'s dependency, `rmeta_aux.rs`, as both an rlib
+// and an rmeta crate. By default, rustc should give the metadata crate (rmeta)
+// precedence over the rust-lib (rlib). This test inspects the contents of the binary
+// and that the correct (rmeta) crate was used.
+// rlibs being preferred could indicate a resurgence of the -Zbinary-dep-depinfo bug
+// seen in #68298.
+// See https://github.com/rust-lang/rust/pull/37681
+
+//@ ignore-cross-compile
+
+use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rustc};
+
+fn main() {
+    rustc().input("rmeta_aux.rs").crate_type("rlib").emit("link,metadata").run();
+    rustc().input("lib.rs").crate_type("rlib").emit("dep-info").arg("-Zbinary-dep-depinfo").run();
+    invalid_utf8_contains("lib.d", "librmeta_aux.rmeta");
+    invalid_utf8_not_contains("lib.d", "librmeta_aux.rlib");
+}
diff --git a/tests/ui-fulldeps/deriving-global.rs b/tests/ui-fulldeps/deriving-global.rs
index 7783010be44..0ba149c9ad6 100644
--- a/tests/ui-fulldeps/deriving-global.rs
+++ b/tests/ui-fulldeps/deriving-global.rs
@@ -17,18 +17,21 @@ mod submod {
     // if any of these are implemented without global calls for any
     // function calls, then being in a submodule will (correctly)
     // cause errors about unrecognised module `std` (or `extra`)
+    #[allow(dead_code)]
     #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
     enum A {
         A1(usize),
         A2(isize),
     }
 
+    #[allow(dead_code)]
     #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
     struct B {
         x: usize,
         y: isize,
     }
 
+    #[allow(dead_code)]
     #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
     struct C(usize, isize);
 }
diff --git a/tests/ui-fulldeps/deriving-hygiene.rs b/tests/ui-fulldeps/deriving-hygiene.rs
index a3a6f9e022e..f948d6ac544 100644
--- a/tests/ui-fulldeps/deriving-hygiene.rs
+++ b/tests/ui-fulldeps/deriving-hygiene.rs
@@ -20,6 +20,7 @@ pub const s: u8 = 1;
 pub const state: u8 = 1;
 pub const cmp: u8 = 1;
 
+#[allow(dead_code)]
 #[derive(Ord, Eq, PartialOrd, PartialEq, Debug, Decodable, Encodable, Hash)]
 struct Foo {}
 
diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr
index c74186285f9..ea58ca97cfa 100644
--- a/tests/ui/argument-suggestions/basic.stderr
+++ b/tests/ui/argument-suggestions/basic.stderr
@@ -16,16 +16,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/basic.rs:21:5
    |
 LL |     extra("");
-   |     ^^^^^ --
-   |           |
-   |           unexpected argument of type `&'static str`
-   |           help: remove the extra argument
+   |     ^^^^^ -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/basic.rs:14:4
    |
 LL | fn extra() {}
    |    ^^^^^
+help: remove the extra argument
+   |
+LL -     extra("");
+LL +     extra();
+   |
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/basic.rs:22:5
diff --git a/tests/ui/argument-suggestions/exotic-calls.stderr b/tests/ui/argument-suggestions/exotic-calls.stderr
index ff795b507f2..aca3b8a3433 100644
--- a/tests/ui/argument-suggestions/exotic-calls.stderr
+++ b/tests/ui/argument-suggestions/exotic-calls.stderr
@@ -2,61 +2,69 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:2:5
    |
 LL |     t(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: callable defined here
   --> $DIR/exotic-calls.rs:1:11
    |
 LL | fn foo<T: Fn()>(t: T) {
    |           ^^^^
+help: remove the extra argument
+   |
+LL -     t(1i32);
+LL +     t();
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:7:5
    |
 LL |     t(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: type parameter defined here
   --> $DIR/exotic-calls.rs:6:11
    |
 LL | fn bar(t: impl Fn()) {
    |           ^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     t(1i32);
+LL +     t();
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:16:5
    |
 LL |     baz()(1i32)
-   |     ^^^^^ ----
-   |           |
-   |           unexpected argument of type `i32`
-   |           help: remove the extra argument
+   |     ^^^^^ ---- unexpected argument of type `i32`
    |
 note: opaque type defined here
   --> $DIR/exotic-calls.rs:11:13
    |
 LL | fn baz() -> impl Fn() {
    |             ^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     baz()(1i32)
+LL +     baz()()
+   |
 
 error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/exotic-calls.rs:22:5
    |
 LL |     x(1i32);
-   |     ^ ----
-   |       |
-   |       unexpected argument of type `i32`
-   |       help: remove the extra argument
+   |     ^ ---- unexpected argument of type `i32`
    |
 note: closure defined here
   --> $DIR/exotic-calls.rs:21:13
    |
 LL |     let x = || {};
    |             ^^
+help: remove the extra argument
+   |
+LL -     x(1i32);
+LL +     x();
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr
index 5ad8e35920a..dec3da75186 100644
--- a/tests/ui/argument-suggestions/extra_arguments.stderr
+++ b/tests/ui/argument-suggestions/extra_arguments.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/extra_arguments.rs:19:3
    |
 LL |   empty("");
-   |   ^^^^^ --
-   |         |
-   |         unexpected argument of type `&'static str`
-   |         help: remove the extra argument
+   |   ^^^^^ -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:1:4
    |
 LL | fn empty() {}
    |    ^^^^^
+help: remove the extra argument
+   |
+LL -   empty("");
+LL +   empty();
+   |
 
 error[E0061]: this function takes 0 arguments but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:20:3
@@ -36,31 +38,35 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:22:3
    |
 LL |   one_arg(1, 1);
-   |   ^^^^^^^  ---
-   |            | |
-   |            | unexpected argument of type `{integer}`
-   |            help: remove the extra argument
+   |   ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, 1);
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:23:3
    |
 LL |   one_arg(1, "");
-   |   ^^^^^^^  ----
-   |            | |
-   |            | unexpected argument of type `&'static str`
-   |            help: remove the extra argument
+   |   ^^^^^^^    -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, "");
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:24:3
@@ -85,61 +91,69 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:26:3
    |
 LL |   two_arg_same(1, 1, 1);
-   |   ^^^^^^^^^^^^     ---
-   |                    | |
-   |                    | unexpected argument of type `{integer}`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^       - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1, 1);
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:27:3
    |
 LL |   two_arg_same(1, 1, 1.0);
-   |   ^^^^^^^^^^^^     -----
-   |                    | |
-   |                    | unexpected argument of type `{float}`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^       --- unexpected argument of type `{float}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1, 1.0);
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:29:3
    |
 LL |   two_arg_diff(1, 1, "");
-   |   ^^^^^^^^^^^^  ---
-   |                 | |
-   |                 | unexpected argument of type `{integer}`
-   |                 help: remove the extra argument
+   |   ^^^^^^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, 1, "");
+LL +   two_arg_diff(1, "");
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:30:3
    |
 LL |   two_arg_diff(1, "", "");
-   |   ^^^^^^^^^^^^      ----
-   |                     | |
-   |                     | unexpected argument of type `&'static str`
-   |                     help: remove the extra argument
+   |   ^^^^^^^^^^^^        -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, "", "");
+LL +   two_arg_diff(1, "");
+   |
 
 error[E0061]: this function takes 2 arguments but 4 arguments were supplied
   --> $DIR/extra_arguments.rs:31:3
@@ -183,70 +197,75 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:35:3
    |
 LL |   two_arg_same(1, 1,     "");
-   |   ^^^^^^^^^^^^     --------
-   |                    |     |
-   |                    |     unexpected argument of type `&'static str`
-   |                    help: remove the extra argument
+   |   ^^^^^^^^^^^^           -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -   two_arg_same(1, 1,     "");
+LL +   two_arg_same(1, 1);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:36:3
    |
 LL |   two_arg_diff(1, 1,     "");
-   |   ^^^^^^^^^^^^  ---
-   |                 | |
-   |                 | unexpected argument of type `{integer}`
-   |                 help: remove the extra argument
+   |   ^^^^^^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -   two_arg_diff(1, 1,     "");
+LL +   two_arg_diff(1,     "");
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:37:3
    |
-LL |     two_arg_same(
-   |     ^^^^^^^^^^^^
-LL |       1,
-LL |       1,
-   |  ______-
-LL | |     ""
-   | |     --
-   | |_____||
-   |       |help: remove the extra argument
-   |       unexpected argument of type `&'static str`
+LL |   two_arg_same(
+   |   ^^^^^^^^^^^^
+...
+LL |     ""
+   |     -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
    |
 LL | fn two_arg_same(_a: i32, _b: i32) {}
    |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL -     1,
+LL -     ""
+LL +     1
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:43:3
    |
-LL |     two_arg_diff(
-   |     ^^^^^^^^^^^^
-LL |       1,
-   |  ______-
-LL | |     1,
-   | |     -
-   | |     |
-   | |_____unexpected argument of type `{integer}`
-   |       help: remove the extra argument
+LL |   two_arg_diff(
+   |   ^^^^^^^^^^^^
+LL |     1,
+LL |     1,
+   |     - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
    |
 LL | fn two_arg_diff(_a: i32, _b: &str) {}
    |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL -     1,
+   |
 
 error[E0061]: this function takes 0 arguments but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:8:9
@@ -310,61 +329,69 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:53:3
    |
 LL |   one_arg(1, panic!());
-   |   ^^^^^^^  ----------
-   |            | |
-   |            | unexpected argument
-   |            help: remove the extra argument
+   |   ^^^^^^^    -------- unexpected argument
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(1, panic!());
+LL +   one_arg(1);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:54:3
    |
 LL |   one_arg(panic!(), 1);
-   |   ^^^^^^^         ---
-   |                   | |
-   |                   | unexpected argument of type `{integer}`
-   |                   help: remove the extra argument
+   |   ^^^^^^^           - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(panic!(), 1);
+LL +   one_arg(panic!());
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:55:3
    |
 LL |   one_arg(stringify!($e), 1);
-   |   ^^^^^^^               ---
-   |                         | |
-   |                         | unexpected argument of type `{integer}`
-   |                         help: remove the extra argument
+   |   ^^^^^^^                 - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(stringify!($e), 1);
+LL +   one_arg(stringify!($e));
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:60:3
    |
 LL |   one_arg(for _ in 1.. {}, 1);
-   |   ^^^^^^^                ---
-   |                          | |
-   |                          | unexpected argument of type `{integer}`
-   |                          help: remove the extra argument
+   |   ^^^^^^^                  - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
    |
 LL | fn one_arg<T>(_a: T) {}
    |    ^^^^^^^    -----
+help: remove the extra argument
+   |
+LL -   one_arg(for _ in 1.. {}, 1);
+LL +   one_arg(for _ in 1.. {});
+   |
 
 error: aborting due to 22 previous errors
 
diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
index 7c4daa3ffe9..dc293945eb6 100644
--- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
+++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr
@@ -32,91 +32,103 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:10:5
    |
 LL |     add_one(2, 2);
-   |     ^^^^^^^  ---
-   |              | |
-   |              | unexpected argument of type `{integer}`
-   |              help: remove the extra argument
+   |     ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(2, 2);
+LL +     add_one(2);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:11:5
    |
 LL |     add_one(no_such_local, 10);
-   |     ^^^^^^^ ---------------
-   |             |
-   |             unexpected argument
-   |             help: remove the extra argument
+   |     ^^^^^^^ ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(no_such_local, 10);
+LL +     add_one(10);
+   |
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:13:5
    |
 LL |     add_one(10, no_such_local);
-   |     ^^^^^^^   ---------------
-   |               | |
-   |               | unexpected argument
-   |               help: remove the extra argument
+   |     ^^^^^^^     ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:1:4
    |
 LL | fn add_one(x: i32) -> i32 {
    |    ^^^^^^^ ------
+help: remove the extra argument
+   |
+LL -     add_one(10, no_such_local);
+LL +     add_one(10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:15:5
    |
 LL |     add_two(10, no_such_local, 10);
-   |     ^^^^^^^   ---------------
-   |               | |
-   |               | unexpected argument
-   |               help: remove the extra argument
+   |     ^^^^^^^     ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(10, no_such_local, 10);
+LL +     add_two(10, 10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:17:5
    |
 LL |     add_two(no_such_local, 10, 10);
-   |     ^^^^^^^ ---------------
-   |             |
-   |             unexpected argument
-   |             help: remove the extra argument
+   |     ^^^^^^^ ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(no_such_local, 10, 10);
+LL +     add_two(10, 10);
+   |
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/suggest-better-removing-issue-126246.rs:19:5
    |
 LL |     add_two(10, 10, no_such_local);
-   |     ^^^^^^^       ---------------
-   |                   | |
-   |                   | unexpected argument
-   |                   help: remove the extra argument
+   |     ^^^^^^^         ------------- unexpected argument
    |
 note: function defined here
   --> $DIR/suggest-better-removing-issue-126246.rs:5:4
    |
 LL | fn add_two(x: i32, y: i32) -> i32 {
    |    ^^^^^^^ ------  ------
+help: remove the extra argument
+   |
+LL -     add_two(10, 10, no_such_local);
+LL +     add_two(10, 10);
+   |
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr
index 7ef433d859f..b4ed99f36f4 100644
--- a/tests/ui/associated-types/defaults-specialization.stderr
+++ b/tests/ui/associated-types/defaults-specialization.stderr
@@ -12,10 +12,7 @@ error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:19:18
    |
 LL |     fn make() -> u8 { 0 }
-   |                  ^^
-   |                  |
-   |                  expected associated type, found `u8`
-   |                  help: change the output type to match the trait: `<A<T> as Tr>::Ty`
+   |                  ^^ expected associated type, found `u8`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -24,6 +21,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <A<T> as Tr>::Ty`
               found signature `fn() -> u8`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <A<T> as Tr>::Ty { 0 }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:35:18
@@ -32,10 +33,7 @@ LL |     default type Ty = bool;
    |     ----------------------- associated type is `default` and may be overridden
 LL |
 LL |     fn make() -> bool { true }
-   |                  ^^^^
-   |                  |
-   |                  expected associated type, found `bool`
-   |                  help: change the output type to match the trait: `<B<T> as Tr>::Ty`
+   |                  ^^^^ expected associated type, found `bool`
    |
 note: type in trait
   --> $DIR/defaults-specialization.rs:9:18
@@ -44,6 +42,10 @@ LL |     fn make() -> Self::Ty {
    |                  ^^^^^^^^
    = note: expected signature `fn() -> <B<T> as Tr>::Ty`
               found signature `fn() -> bool`
+help: change the output type to match the trait
+   |
+LL |     fn make() -> <B<T> as Tr>::Ty { true }
+   |                  ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/defaults-specialization.rs:10:9
diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr
index 3cc35b21409..b547da7126a 100644
--- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr
+++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr
@@ -1,29 +1,29 @@
-error[E0311]: the parameter type `U` may not live long enough
+error[E0311]: the parameter type `T` may not live long enough
   --> $DIR/async-generics-and-bounds.rs:9:5
    |
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
    |     ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |            |
-   |     |            the parameter type `U` must be valid for the anonymous lifetime as defined here...
+   |     |            the parameter type `T` must be valid for the anonymous lifetime as defined here...
    |     ...so that the reference type `&(T, U)` does not outlive the data it points at
    |
 help: consider adding an explicit lifetime bound
    |
-LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a;
+LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a;
    |                 ++++  ++           ++                                       +++++++
 
-error[E0311]: the parameter type `T` may not live long enough
+error[E0311]: the parameter type `U` may not live long enough
   --> $DIR/async-generics-and-bounds.rs:9:5
    |
 LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
    |     ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |            |
-   |     |            the parameter type `T` must be valid for the anonymous lifetime as defined here...
+   |     |            the parameter type `U` must be valid for the anonymous lifetime as defined here...
    |     ...so that the reference type `&(T, U)` does not outlive the data it points at
    |
 help: consider adding an explicit lifetime bound
    |
-LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a;
+LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a;
    |                 ++++  ++           ++                                       +++++++
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr
index 3b27f8fe2f0..2e29a9bcc77 100644
--- a/tests/ui/async-await/in-trait/async-generics.stderr
+++ b/tests/ui/async-await/in-trait/async-generics.stderr
@@ -1,29 +1,29 @@
-error[E0311]: the parameter type `U` may not live long enough
+error[E0311]: the parameter type `T` may not live long enough
   --> $DIR/async-generics.rs:6:5
    |
 LL |     async fn foo(&self) -> &(T, U);
    |     ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
    |     |            |
-   |     |            the parameter type `U` must be valid for the anonymous lifetime as defined here...
+   |     |            the parameter type `T` must be valid for the anonymous lifetime as defined here...
    |     ...so that the reference type `&(T, U)` does not outlive the data it points at
    |
 help: consider adding an explicit lifetime bound
    |
-LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a;
+LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a;
    |                 ++++  ++           ++        +++++++++++
 
-error[E0311]: the parameter type `T` may not live long enough
+error[E0311]: the parameter type `U` may not live long enough
   --> $DIR/async-generics.rs:6:5
    |
 LL |     async fn foo(&self) -> &(T, U);
    |     ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
    |     |            |
-   |     |            the parameter type `T` must be valid for the anonymous lifetime as defined here...
+   |     |            the parameter type `U` must be valid for the anonymous lifetime as defined here...
    |     ...so that the reference type `&(T, U)` does not outlive the data it points at
    |
 help: consider adding an explicit lifetime bound
    |
-LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a;
+LL |     async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a;
    |                 ++++  ++           ++        +++++++++++
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr
index a87b713c2b4..a3a31f43447 100644
--- a/tests/ui/compare-method/bad-self-type.stderr
+++ b/tests/ui/compare-method/bad-self-type.stderr
@@ -2,22 +2,20 @@ error[E0053]: method `poll` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:10:13
    |
 LL |     fn poll(self, _: &mut Context<'_>) -> Poll<()> {
-   |             ^^^^
-   |             |
-   |             expected `Pin<&mut MyFuture>`, found `MyFuture`
-   |             help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>`
+   |             ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture`
    |
    = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>`
               found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> {
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:22:18
    |
 LL |     fn foo(self: Box<Self>) {}
-   |            ------^^^^^^^^^
-   |            |     |
-   |            |     expected `MyFuture`, found `Box<MyFuture>`
-   |            help: change the self-receiver type to match the trait: `self`
+   |                  ^^^^^^^^^ expected `MyFuture`, found `Box<MyFuture>`
    |
 note: type in trait
   --> $DIR/bad-self-type.rs:17:12
@@ -26,6 +24,10 @@ LL |     fn foo(self);
    |            ^^^^
    = note: expected signature `fn(MyFuture)`
               found signature `fn(Box<MyFuture>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn foo(self) {}
+   |            ~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/bad-self-type.rs:24:17
@@ -39,7 +41,7 @@ note: type in trait
 LL |     fn bar(self) -> Option<()>;
    |                     ^^^^^^^^^^
    = note: expected signature `fn(MyFuture) -> Option<()>`
-              found signature `fn(MyFuture)`
+              found signature `fn(MyFuture) -> ()`
 help: change the output type to match the trait
    |
 LL |     fn bar(self) -> Option<()> {}
diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr
index 52e23d03b14..f05c9939c00 100644
--- a/tests/ui/compare-method/issue-90444.stderr
+++ b/tests/ui/compare-method/issue-90444.stderr
@@ -2,25 +2,27 @@ error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:3:16
    |
 LL |     fn from(_: fn((), (), &mut ())) -> Self {
-   |                ^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                types differ in mutability
-   |                help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())`
+   |                ^^^^^^^^^^^^^^^^^^^ types differ in mutability
    |
    = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A`
               found signature `fn(for<'a> fn((), (), &'a mut ())) -> A`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: for<'a> fn((), (), &'a ())) -> Self {
+   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0053]: method `from` has an incompatible type for trait
   --> $DIR/issue-90444.rs:11:16
    |
 LL |     fn from(_: fn((), (), u64)) -> Self {
-   |                ^^^^^^^^^^^^^^^
-   |                |
-   |                expected `u32`, found `u64`
-   |                help: change the parameter type to match the trait: `fn((), (), u32)`
+   |                ^^^^^^^^^^^^^^^ expected `u32`, found `u64`
    |
    = note: expected signature `fn(fn((), (), u32)) -> B`
               found signature `fn(fn((), (), u64)) -> B`
+help: change the parameter type to match the trait
+   |
+LL |     fn from(_: fn((), (), u32)) -> Self {
+   |                ~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr
index 8a439acee13..1e8266e213d 100644
--- a/tests/ui/compare-method/reordered-type-param.stderr
+++ b/tests/ui/compare-method/reordered-type-param.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `b` has an incompatible type for trait
   --> $DIR/reordered-type-param.rs:16:30
    |
 LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
-   |        -       -             ^
-   |        |       |             |
-   |        |       |             expected type parameter `F`, found type parameter `G`
-   |        |       |             help: change the parameter type to match the trait: `F`
+   |        -       -             ^ expected type parameter `F`, found type parameter `G`
+   |        |       |
    |        |       found type parameter
    |        expected type parameter
    |
@@ -18,6 +16,10 @@ LL |   fn b<C:Clone,D>(&self, x: C) -> C;
               found signature `fn(&E, G) -> G`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |   fn b<F:Clone,G>(&self, _x: F) -> G { panic!() }
+   |                              ~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-86535-2.rs b/tests/ui/const-generics/issues/issue-86535-2.rs
index 1ba3b6d5347..bd9431dbc85 100644
--- a/tests/ui/const-generics/issues/issue-86535-2.rs
+++ b/tests/ui/const-generics/issues/issue-86535-2.rs
@@ -7,6 +7,7 @@ pub trait Foo {
     fn foo() where [(); Self::ASSOC_C]:;
 }
 
+#[allow(dead_code)]
 struct Bar<const N: &'static ()>;
 impl<const N: &'static ()> Foo for Bar<N> {
     const ASSOC_C: usize = 3;
diff --git a/tests/ui/const-generics/issues/issue-86535.rs b/tests/ui/const-generics/issues/issue-86535.rs
index dd6bc88ad19..cd9934a4a99 100644
--- a/tests/ui/const-generics/issues/issue-86535.rs
+++ b/tests/ui/const-generics/issues/issue-86535.rs
@@ -2,6 +2,7 @@
 #![feature(adt_const_params, generic_const_exprs)]
 #![allow(incomplete_features, unused_variables)]
 
+#[allow(dead_code)]
 struct F<const S: &'static str>;
 impl<const S: &'static str> X for F<{ S }> {
     const W: usize = 3;
diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs
index 57767e96596..e71f88b8d5f 100644
--- a/tests/ui/consts/offset_from_ub.rs
+++ b/tests/ui/consts/offset_from_ub.rs
@@ -92,6 +92,14 @@ pub const TOO_FAR_APART2: isize = {
     unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed
     //~| too far before
 };
+pub const TOO_FAR_APART3: isize = {
+    let ptr1 = &0u8 as *const u8;
+    let ptr2 = ptr1.wrapping_offset(isize::MIN);
+    // The result of this would be `isize::MIN`, which *does* fit in an `isize`, but its
+    // absolute value does not. (Also anyway there cannot be an allocation of that size.)
+    unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed
+    //~| too far before
+};
 
 const WRONG_ORDER_UNSIGNED: usize = {
     let a = ['a', 'b', 'c'];
diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr
index 65f75a6e058..7caf6247b9e 100644
--- a/tests/ui/consts/offset_from_ub.stderr
+++ b/tests/ui/consts/offset_from_ub.stderr
@@ -60,13 +60,19 @@ LL |     unsafe { ptr_offset_from(ptr1, ptr2) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/offset_from_ub.rs:99:14
+  --> $DIR/offset_from_ub.rs:100:14
+   |
+LL |     unsafe { ptr_offset_from(ptr1, ptr2) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/offset_from_ub.rs:107:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(p, p.add(2) ) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/offset_from_ub.rs:106:14
+  --> $DIR/offset_from_ub.rs:114:14
    |
 LL |     unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second
@@ -79,7 +85,7 @@ error[E0080]: evaluation of constant value failed
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
 note: inside `OFFSET_VERY_FAR1`
-  --> $DIR/offset_from_ub.rs:115:14
+  --> $DIR/offset_from_ub.rs:123:14
    |
 LL |     unsafe { ptr2.offset_from(ptr1) }
    |              ^^^^^^^^^^^^^^^^^^^^^^
@@ -92,11 +98,11 @@ error[E0080]: evaluation of constant value failed
 note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
   --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
 note: inside `OFFSET_VERY_FAR2`
-  --> $DIR/offset_from_ub.rs:121:14
+  --> $DIR/offset_from_ub.rs:129:14
    |
 LL |     unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 13 previous errors
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr
index 9b0cf069824..efd2af6d609 100644
--- a/tests/ui/error-codes/E0057.stderr
+++ b/tests/ui/error-codes/E0057.stderr
@@ -18,16 +18,18 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/E0057.rs:5:13
    |
 LL |     let c = f(2, 3);
-   |             ^  ---
-   |                | |
-   |                | unexpected argument of type `{integer}`
-   |                help: remove the extra argument
+   |             ^    - unexpected argument of type `{integer}`
    |
 note: closure defined here
   --> $DIR/E0057.rs:2:13
    |
 LL |     let f = |x| x * 3;
    |             ^^^
+help: remove the extra argument
+   |
+LL -     let c = f(2, 3);
+LL +     let c = f(2);
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/error-codes/E0308.stderr b/tests/ui/error-codes/E0308.stderr
index bc6c5a632a1..709b3119276 100644
--- a/tests/ui/error-codes/E0308.stderr
+++ b/tests/ui/error-codes/E0308.stderr
@@ -5,7 +5,7 @@ LL |     fn size_of<T>();
    |                    ^ expected `usize`, found `()`
    |
    = note: expected signature `extern "rust-intrinsic" fn() -> usize`
-              found signature `extern "rust-intrinsic" fn()`
+              found signature `extern "rust-intrinsic" fn() -> ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr b/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr
index d1f4ed5cb04..696326157ce 100644
--- a/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr
+++ b/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr
@@ -2,12 +2,13 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
   --> $DIR/feature-gate-negate-unsigned.rs:10:23
    |
 LL |     let _max: usize = -1;
-   |                       ^^
-   |                       |
-   |                       cannot apply unary operator `-`
-   |                       help: you may have meant the maximum value of `usize`: `usize::MAX`
+   |                       ^^ cannot apply unary operator `-`
    |
    = note: unsigned values cannot be negated
+help: you may have meant the maximum value of `usize`
+   |
+LL |     let _max: usize = usize::MAX;
+   |                       ~~~~~~~~~~
 
 error[E0600]: cannot apply unary operator `-` to type `u8`
   --> $DIR/feature-gate-negate-unsigned.rs:14:14
diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index 1b9febd431d..584724dfe59 100644
--- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -89,13 +89,14 @@ error[E0053]: method `call` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32
    |
 LL |     extern "rust-call" fn call(self, args: ()) -> () {}
-   |                                ^^^^
-   |                                |
-   |                                expected `&Foo`, found `Foo`
-   |                                help: change the self-receiver type to match the trait: `&self`
+   |                                ^^^^ expected `&Foo`, found `Foo`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _`
-              found signature `extern "rust-call" fn(Foo, ())`
+              found signature `extern "rust-call" fn(Foo, ()) -> ()`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call(&self, args: ()) -> () {}
+   |                                ~~~~~
 
 error[E0183]: manual implementations of `FnOnce` are experimental
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
@@ -158,13 +159,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36
    |
 LL |     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
-   |                                    ^^^^^
-   |                                    |
-   |                                    types differ in mutability
-   |                                    help: change the self-receiver type to match the trait: `&mut self`
+   |                                    ^^^^^ types differ in mutability
    |
    = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _`
-              found signature `extern "rust-call" fn(&Bar, ())`
+              found signature `extern "rust-call" fn(&Bar, ()) -> ()`
+help: change the self-receiver type to match the trait
+   |
+LL |     extern "rust-call" fn call_mut(&mut self, args: ()) -> () {}
+   |                                    ~~~~~~~~~
 
 error[E0046]: not all trait items implemented, missing: `Output`
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1
diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
index 0b3331b040d..5000601e90f 100644
--- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
+++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr
@@ -10,7 +10,7 @@ LL |     x = foo::<()>;
    |         ^^^^^^^^^ expected fn item, found a different fn item
    |
    = note: expected fn item `fn(F) -> F {bar::<F>}`
-              found fn item `fn(()) {foo::<()>}`
+              found fn item `fn(()) -> () {foo::<()>}`
 
 error[E0308]: mismatched types
   --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:27:9
@@ -26,7 +26,7 @@ LL |     let mut x = bar::<()>;
 LL |     x = foo::<I>;
    |         ^^^^^^^^ expected fn item, found a different fn item
    |
-   = note: expected fn item `fn(()) {bar::<()>}`
+   = note: expected fn item `fn(()) -> () {bar::<()>}`
               found fn item `fn(I) -> I {foo::<I>}`
 help: use parentheses to call this function
    |
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
index 886fc1d0058..3c4499f0173 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed
@@ -1,6 +1,8 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct S<T>(T);
+#[allow(dead_code)]
 struct S2;
 
 impl<T: Default> Default for S<T> {
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
index f3271993867..ac078329524 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs
@@ -1,6 +1,8 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct S<T>(T);
+#[allow(dead_code)]
 struct S2;
 
 impl<T: Default> impl Default for S<T> {
diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
index 5aafc8b64d4..91c7da5a04f 100644
--- a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
+++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr
@@ -1,23 +1,23 @@
 error: unexpected `impl` keyword
-  --> $DIR/extra-impl-in-trait-impl.rs:6:18
+  --> $DIR/extra-impl-in-trait-impl.rs:8:18
    |
 LL | impl<T: Default> impl Default for S<T> {
    |                  ^^^^^ help: remove the extra `impl`
    |
 note: this is parsed as an `impl Trait` type, but a trait is expected at this position
-  --> $DIR/extra-impl-in-trait-impl.rs:6:18
+  --> $DIR/extra-impl-in-trait-impl.rs:8:18
    |
 LL | impl<T: Default> impl Default for S<T> {
    |                  ^^^^^^^^^^^^
 
 error: unexpected `impl` keyword
-  --> $DIR/extra-impl-in-trait-impl.rs:12:6
+  --> $DIR/extra-impl-in-trait-impl.rs:14:6
    |
 LL | impl impl Default for S2 {
    |      ^^^^^ help: remove the extra `impl`
    |
 note: this is parsed as an `impl Trait` type, but a trait is expected at this position
-  --> $DIR/extra-impl-in-trait-impl.rs:12:6
+  --> $DIR/extra-impl-in-trait-impl.rs:14:6
    |
 LL | impl impl Default for S2 {
    |      ^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
index 7046e729e18..90c31c9e3fc 100644
--- a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/impl-generic-mismatch-ab.rs:8:32
    |
 LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
-   |            -                   ^^^^^^^^^^^
-   |            |                   |
-   |            |                   expected type parameter `B`, found type parameter `impl Debug`
-   |            |                   help: change the parameter type to match the trait: `&B`
+   |            -                   ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
+   |            |
    |            expected type parameter
    |
 note: type in trait
@@ -17,6 +15,10 @@ LL |     fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
               found signature `fn(&(), &impl Debug, &B)`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+help: change the parameter type to match the trait
+   |
+LL |     fn foo<B: Debug>(&self, a: &B, b: &B) { }
+   |                                ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
index 8e61a65abe4..75cbe43eeb4 100644
--- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -27,10 +27,7 @@ LL |         type Ty = impl Sized;
    |                   ---------- the expected opaque type
 LL |
 LL |         fn method() -> () {}
-   |                        ^^
-   |                        |
-   |                        expected opaque type, found `()`
-   |                        help: change the output type to match the trait: `<() as compare_method::Trait>::Ty`
+   |                        ^^ expected opaque type, found `()`
    |
 note: type in trait
   --> $DIR/in-assoc-type-unconstrained.rs:17:24
@@ -38,12 +35,16 @@ note: type in trait
 LL |         fn method() -> Self::Ty;
    |                        ^^^^^^^^
    = note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
-              found signature `fn()`
+              found signature `fn() -> ()`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
   --> $DIR/in-assoc-type-unconstrained.rs:22:12
    |
 LL |         fn method() -> () {}
    |            ^^^^^^
+help: change the output type to match the trait
+   |
+LL |         fn method() -> <() as compare_method::Trait>::Ty {}
+   |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/in-assoc-type-unconstrained.rs:20:19
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
index 2231205327c..6f6b787b6fe 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr
@@ -2,10 +2,8 @@ error[E0053]: method `early` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:55:27
    |
 LL |     fn early<'late, T>(_: &'late ()) {}
-   |                     -     ^^^^^^^^^
-   |                     |     |
-   |                     |     expected type parameter `T`, found `()`
-   |                     |     help: change the parameter type to match the trait: `&T`
+   |                     -     ^^^^^^^^^ expected type parameter `T`, found `()`
+   |                     |
    |                     expected this type parameter
    |
 note: type in trait
@@ -15,6 +13,10 @@ LL |     fn early<'early, T>(x: &'early T) -> impl Sized;
    |                            ^^^^^^^^^
    = note: expected signature `fn(&T)`
               found signature `fn(&'late ())`
+help: change the parameter type to match the trait
+   |
+LL |     fn early<'late, T>(_: &T) {}
+   |                           ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
index ec2a126865d..9e18517e48c 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:11:15
    |
 LL |     fn owo(_: u8) {}
-   |               ^^
-   |               |
-   |               expected `()`, found `u8`
-   |               help: change the parameter type to match the trait: `()`
+   |               ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:6:15
@@ -14,6 +11,10 @@ LL |     fn owo(x: ()) -> impl Sized;
    |               ^^
    = note: expected signature `fn(())`
               found signature `fn(u8)`
+help: change the parameter type to match the trait
+   |
+LL |     fn owo(_: ()) {}
+   |               ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
index 4d3e64e8050..c01d7322d11 100644
--- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
+++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait
   --> $DIR/method-signature-matches.rs:22:21
    |
 LL |     async fn owo(_: u8) {}
-   |                     ^^
-   |                     |
-   |                     expected `()`, found `u8`
-   |                     help: change the parameter type to match the trait: `()`
+   |                     ^^ expected `()`, found `u8`
    |
 note: type in trait
   --> $DIR/method-signature-matches.rs:17:21
@@ -14,6 +11,10 @@ LL |     async fn owo(x: ()) {}
    |                     ^^
    = note: expected signature `fn(()) -> _`
               found signature `fn(u8) -> _`
+help: change the parameter type to match the trait
+   |
+LL |     async fn owo(_: ()) {}
+   |                     ~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
index d7fc40fa342..1f8a0d5edd7 100644
--- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
@@ -75,10 +75,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:10:17
    |
 LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<'static>`, found `i32`
-   |                 help: change the output type to match the trait: `Wrapper<'static>`
+   |                 ^^^ expected `Wrapper<'static>`, found `i32`
    |
 note: type in trait
   --> $DIR/opaque-and-lifetime-mismatch.rs:4:17
@@ -87,6 +84,10 @@ LL |     fn bar() -> Wrapper<impl Sized>;
    |                 ^^^^^^^^^^^^^^^^^^^
    = note: expected signature `fn() -> Wrapper<'static>`
               found signature `fn() -> i32`
+help: change the output type to match the trait
+   |
+LL |     fn bar() -> Wrapper<'static> {
+   |                 ~~~~~~~~~~~~~~~~
 
 error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
   --> $DIR/opaque-and-lifetime-mismatch.rs:24:17
diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
index b8a8e2401b2..8c9f2656015 100644
--- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr
+++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr
@@ -5,10 +5,7 @@ LL | default impl<U> Foo for U
    |              - found this type parameter
 ...
 LL |     fn bar(&self) -> U {
-   |                      ^
-   |                      |
-   |                      expected associated type, found type parameter `U`
-   |                      help: change the output type to match the trait: `impl Sized`
+   |                      ^ expected associated type, found type parameter `U`
    |
 note: type in trait
   --> $DIR/specialization-broken.rs:8:22
@@ -17,6 +14,10 @@ LL |     fn bar(&self) -> impl Sized;
    |                      ^^^^^^^^^^
    = note: expected signature `fn(&_) -> impl Sized`
               found signature `fn(&_) -> U`
+help: change the output type to match the trait
+   |
+LL |     fn bar(&self) -> impl Sized {
+   |                      ~~~~~~~~~~
 
 error: method with return-position `impl Trait` in trait cannot be specialized
   --> $DIR/specialization-broken.rs:15:5
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
index 6d417488533..caaac5434c5 100644
--- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -57,31 +57,35 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:17:20
    |
 LL |     let old_path = frob("hello");
-   |                    ^^^^ -------
-   |                         |
-   |                         unexpected argument of type `&'static str`
-   |                         help: remove the extra argument
+   |                    ^^^^ ------- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:5:4
    |
 LL | fn frob() -> impl Fn<P, Output = T> + '_ {}
    |    ^^^^
+help: remove the extra argument
+   |
+LL -     let old_path = frob("hello");
+LL +     let old_path = frob();
+   |
 
 error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:20:5
    |
 LL |     open_parent(&old_path)
-   |     ^^^^^^^^^^^ ---------
-   |                 |
-   |                 unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
-   |                 help: remove the extra argument
+   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:12:4
    |
 LL | fn open_parent<'path>() {
    |    ^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     open_parent(&old_path)
+LL +     open_parent()
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index 4352af1c0df..3692cc77b0f 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -26,13 +26,14 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the found opaque type
 ...
 LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected `a::Bar`, found opaque type
-   |                              help: change the parameter type to match the trait: `&(a::Bar, i32)`
+   |                              ^^^^^^^^^^^ expected `a::Bar`, found opaque type
    |
    = note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _`
               found signature `fn(&a::Bar, &(a::Foo, _)) -> _`
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(a::Bar, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
@@ -49,10 +50,7 @@ LL |     type Foo = impl PartialEq<(Foo, i32)>;
    |                -------------------------- the expected opaque type
 ...
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
-   |                              ^^^^^^^^^^^
-   |                              |
-   |                              expected opaque type, found `b::Bar`
-   |                              help: change the parameter type to match the trait: `&(b::Foo, i32)`
+   |                              ^^^^^^^^^^^ expected opaque type, found `b::Bar`
    |
    = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
               found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
@@ -61,6 +59,10 @@ note: this item must have the opaque type in its signature in order to be able t
    |
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    |            ^^
+help: change the parameter type to match the trait
+   |
+LL |         fn eq(&self, _other: &(b::Foo, i32)) -> bool {
+   |                              ~~~~~~~~~~~~~~
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr
index 81e4c933e53..989779a6178 100644
--- a/tests/ui/impl-trait/trait_type.stderr
+++ b/tests/ui/impl-trait/trait_type.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `fmt` has an incompatible type for trait
   --> $DIR/trait_type.rs:7:21
    |
 LL |    fn fmt(&self, x: &str) -> () { }
-   |                     ^^^^
-   |                     |
-   |                     types differ in mutability
-   |                     help: change the parameter type to match the trait: `&mut Formatter<'_>`
+   |                     ^^^^ types differ in mutability
    |
    = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>`
-              found signature `fn(&MyType, &str)`
+              found signature `fn(&MyType, &str) -> ()`
+help: change the parameter type to match the trait
+   |
+LL |    fn fmt(&self, x: &mut Formatter<'_>) -> () { }
+   |                     ~~~~~~~~~~~~~~~~~~
 
 error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
   --> $DIR/trait_type.rs:12:11
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index bffe0447f8b..f0d259d01de 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -397,10 +397,7 @@ LL |     type Out = impl Debug;
    |                ---------- the expected opaque type
 ...
 LL |     fn in_trait_impl_return() -> impl Debug { () }
-   |                                  ^^^^^^^^^^
-   |                                  |
-   |                                  expected opaque type, found a different opaque type
-   |                                  help: change the output type to match the trait: `<() as DummyTrait>::Out`
+   |                                  ^^^^^^^^^^ expected opaque type, found a different opaque type
    |
 note: type in trait
   --> $DIR/where-allowed.rs:119:34
@@ -410,6 +407,10 @@ LL |     fn in_trait_impl_return() -> Self::Out;
    = note: expected signature `fn() -> <() as DummyTrait>::Out`
               found signature `fn() -> impl Debug`
    = note: distinct uses of `impl Trait` result in different opaque types
+help: change the output type to match the trait
+   |
+LL |     fn in_trait_impl_return() -> <() as DummyTrait>::Out { () }
+   |                                  ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unconstrained opaque type
   --> $DIR/where-allowed.rs:122:16
diff --git a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
index e2ddf474c4a..a5cd057e284 100644
--- a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
+++ b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr
@@ -55,16 +55,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:21:31
    |
 LL |     LendingIterator::for_each(Query::new(&data), Box::new);
-   |                               ^^^^^^^^^^ -----
-   |                                          |
-   |                                          unexpected argument of type `&fn() {data}`
-   |                                          help: remove the extra argument
+   |                               ^^^^^^^^^^ ----- unexpected argument of type `&fn() {data}`
    |
 note: associated function defined here
   --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:17:12
    |
 LL |     pub fn new() -> Self {}
    |            ^^^
+help: remove the extra argument
+   |
+LL -     LendingIterator::for_each(Query::new(&data), Box::new);
+LL +     LendingIterator::for_each(Query::new(), Box::new);
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/issues/issue-16939.stderr b/tests/ui/issues/issue-16939.stderr
index 229ff9f1817..6e0889b8963 100644
--- a/tests/ui/issues/issue-16939.stderr
+++ b/tests/ui/issues/issue-16939.stderr
@@ -2,16 +2,18 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-16939.rs:5:9
    |
 LL |     |t| f(t);
-   |         ^ -
-   |           |
-   |           unexpected argument
-   |           help: remove the extra argument
+   |         ^ - unexpected argument
    |
 note: callable defined here
   --> $DIR/issue-16939.rs:4:12
    |
 LL | fn _foo<F: Fn()> (f: F) {
    |            ^^^^
+help: remove the extra argument
+   |
+LL -     |t| f(t);
+LL +     |t| f();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr
index 2d24a5bbd50..7d6b09cf7f8 100644
--- a/tests/ui/issues/issue-20225.stderr
+++ b/tests/ui/issues/issue-20225.stderr
@@ -4,13 +4,14 @@ error[E0053]: method `call` has an incompatible type for trait
 LL | impl<'a, T> Fn<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
-   |                                           ^^^^
-   |                                           |
-   |                                           expected `&'a T`, found type parameter `T`
-   |                                           help: change the parameter type to match the trait: `(&'a T,)`
+   |                                           ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call(&self, (_,): (&'a T,)) {}
+   |                                           ~~~~~~~~
 
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:11:51
@@ -18,13 +19,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait
 LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
    |          - found this type parameter
 LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
-   |                                                   ^^^^
-   |                                                   |
-   |                                                   expected `&'a T`, found type parameter `T`
-   |                                                   help: change the parameter type to match the trait: `(&'a T,)`
+   |                                                   ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))`
               found signature `extern "rust-call" fn(&mut Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {}
+   |                                                   ~~~~~~~~
 
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:18:47
@@ -33,13 +35,14 @@ LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
    |          - found this type parameter
 ...
 LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
-   |                                               ^^^^
-   |                                               |
-   |                                               expected `&'a T`, found type parameter `T`
-   |                                               help: change the parameter type to match the trait: `(&'a T,)`
+   |                                               ^^^^ expected `&'a T`, found type parameter `T`
    |
    = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))`
               found signature `extern "rust-call" fn(Foo, (_,))`
+help: change the parameter type to match the trait
+   |
+LL |   extern "rust-call" fn call_once(self, (_,): (&'a T,)) {}
+   |                                               ~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/issues/issue-21332.stderr
index 96e0f5fdb31..7c960f7646d 100644
--- a/tests/ui/issues/issue-21332.stderr
+++ b/tests/ui/issues/issue-21332.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `next` has an incompatible type for trait
   --> $DIR/issue-21332.rs:5:27
    |
 LL |     fn next(&mut self) -> Result<i32, i32> { Ok(7) }
-   |                           ^^^^^^^^^^^^^^^^
-   |                           |
-   |                           expected `Option<i32>`, found `Result<i32, i32>`
-   |                           help: change the output type to match the trait: `Option<i32>`
+   |                           ^^^^^^^^^^^^^^^^ expected `Option<i32>`, found `Result<i32, i32>`
    |
    = note: expected signature `fn(&mut S) -> Option<i32>`
               found signature `fn(&mut S) -> Result<i32, i32>`
+help: change the output type to match the trait
+   |
+LL |     fn next(&mut self) -> Option<i32> { Ok(7) }
+   |                           ~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr
index 25f299ae5f3..f18cf66f14d 100644
--- a/tests/ui/issues/issue-4935.stderr
+++ b/tests/ui/issues/issue-4935.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/issue-4935.rs:5:13
    |
 LL | fn main() { foo(5, 6) }
-   |             ^^^  ---
-   |                  | |
-   |                  | unexpected argument of type `{integer}`
-   |                  help: remove the extra argument
+   |             ^^^    - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/issue-4935.rs:3:4
    |
 LL | fn foo(a: usize) {}
    |    ^^^ --------
+help: remove the extra argument
+   |
+LL - fn main() { foo(5, 6) }
+LL + fn main() { foo(5) }
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr
index aa1b1b73bae..2672efe51c9 100644
--- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr
+++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr
@@ -5,7 +5,7 @@ LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpi
    |                                                                                   ^ expected `isize`, found `()`
    |
    = note: expected signature `fn(fn() -> _, _, _, _) -> isize`
-              found signature `fn(fn() -> _, _, _, _)`
+              found signature `fn(fn() -> _, _, _, _) -> ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/dead-code/issue-59003.rs b/tests/ui/lint/dead-code/issue-59003.rs
index e3dcaca5778..319cf2db149 100644
--- a/tests/ui/lint/dead-code/issue-59003.rs
+++ b/tests/ui/lint/dead-code/issue-59003.rs
@@ -4,8 +4,8 @@
 
 #![deny(dead_code)]
 
+#[allow(dead_code)]
 struct Foo {
-    #[allow(dead_code)]
     inner: u32,
 }
 
diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs
new file mode 100644
index 00000000000..25777438456
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs
@@ -0,0 +1,37 @@
+#![deny(dead_code)]
+
+struct Foo(u8); //~ ERROR struct `Foo` is never constructed
+
+enum Bar { //~ ERROR enum `Bar` is never used
+    Var1(u8),
+    Var2(u8),
+}
+
+pub trait Tr1 {
+    fn f1() -> Self;
+}
+
+impl Tr1 for Foo {
+    fn f1() -> Foo {
+        let f = Foo(0);
+        let Foo(tag) = f;
+        Foo(tag)
+    }
+}
+
+impl Tr1 for Bar {
+    fn f1() -> Bar {
+        let b = Bar::Var1(0);
+        let b = if let Bar::Var1(_) = b {
+            Bar::Var1(0)
+        } else {
+            Bar::Var2(0)
+        };
+        match b {
+            Bar::Var1(_) => Bar::Var2(0),
+            Bar::Var2(_) => Bar::Var1(0),
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr
new file mode 100644
index 00000000000..7c1a4b45977
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr
@@ -0,0 +1,20 @@
+error: struct `Foo` is never constructed
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:3:8
+   |
+LL | struct Foo(u8);
+   |        ^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: enum `Bar` is never used
+  --> $DIR/lint-unused-adt-appeared-in-pattern.rs:5:6
+   |
+LL | enum Bar {
+   |      ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs b/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs
new file mode 100644
index 00000000000..43a2e431904
--- /dev/null
+++ b/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs
@@ -0,0 +1,32 @@
+//@ check-pass
+
+#![deny(dead_code)]
+
+#[repr(u8)]
+#[derive(Copy, Clone, Debug)]
+pub enum RecordField {
+    Target = 1,
+    Level,
+    Module,
+    File,
+    Line,
+    NumArgs,
+}
+
+unsafe trait Pod {}
+
+#[repr(transparent)]
+struct RecordFieldWrapper(RecordField);
+
+unsafe impl Pod for RecordFieldWrapper {}
+
+fn try_read<T: Pod>(buf: &[u8]) -> T {
+    unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const T) }
+}
+
+pub fn foo(buf: &[u8]) -> RecordField {
+    let RecordFieldWrapper(tag) = try_read(buf);
+    tag
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
index bf2fc243e81..658cc3d6c61 100644
--- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
+++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs
@@ -1,8 +1,9 @@
 #![deny(dead_code)]
 
 struct T1; //~ ERROR struct `T1` is never constructed
-pub struct T2(i32); //~ ERROR struct `T2` is never constructed
-struct T3;
+struct T2; //~ ERROR struct `T2` is never constructed
+pub struct T3(i32); //~ ERROR struct `T3` is never constructed
+pub struct T4(i32); //~ ERROR field `0` is never read
 
 trait Trait1 { //~ ERROR trait `Trait1` is never used
     const UNUSED: i32;
@@ -11,13 +12,13 @@ trait Trait1 { //~ ERROR trait `Trait1` is never used
 }
 
 pub trait Trait2 {
-    const USED: i32;
-    fn used(&self) {}
+    const MAY_USED: i32;
+    fn may_used(&self) {}
 }
 
 pub trait Trait3 {
-    const USED: i32;
-    fn construct_self() -> Self;
+    const MAY_USED: i32;
+    fn may_used() -> Self;
 }
 
 impl Trait1 for T1 {
@@ -30,23 +31,34 @@ impl Trait1 for T1 {
 impl Trait1 for T2 {
     const UNUSED: i32 = 0;
     fn construct_self() -> Self {
-        T2(0)
+        Self
     }
 }
 
 impl Trait2 for T1 {
-    const USED: i32 = 0;
+    const MAY_USED: i32 = 0;
 }
 
 impl Trait2 for T2 {
-    const USED: i32 = 0;
+    const MAY_USED: i32 = 0;
 }
 
-impl Trait3 for T3 {
-    const USED: i32 = 0;
-    fn construct_self() -> Self {
+impl Trait2 for T3 {
+    const MAY_USED: i32 = 0;
+}
+
+impl Trait3 for T2 {
+    const MAY_USED: i32 = 0;
+    fn may_used() -> Self {
         Self
     }
 }
 
+impl Trait3 for T4 {
+    const MAY_USED: i32 = 0;
+    fn may_used() -> Self {
+        T4(0)
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
index 174096d9398..08c7a5cb4b0 100644
--- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
+++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr
@@ -11,16 +11,32 @@ LL | #![deny(dead_code)]
    |         ^^^^^^^^^
 
 error: struct `T2` is never constructed
-  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12
+  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:8
    |
-LL | pub struct T2(i32);
+LL | struct T2;
+   |        ^^
+
+error: struct `T3` is never constructed
+  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:5:12
+   |
+LL | pub struct T3(i32);
    |            ^^
 
+error: field `0` is never read
+  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:6:15
+   |
+LL | pub struct T4(i32);
+   |            -- ^^^
+   |            |
+   |            field in this struct
+   |
+   = help: consider removing this field
+
 error: trait `Trait1` is never used
-  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7
+  --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:8:7
    |
 LL | trait Trait1 {
    |       ^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.rs b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
index 330ad32dd57..f20b7cb66ee 100644
--- a/tests/ui/lint/dead-code/unused-struct-derive-default.rs
+++ b/tests/ui/lint/dead-code/unused-struct-derive-default.rs
@@ -22,4 +22,5 @@ pub struct T2 {
 
 fn main() {
     let _x: Used = Default::default();
+    let _e: E = Default::default();
 }
diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
index bbb0bd7be70..7422f9a39f3 100644
--- a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
+++ b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr
@@ -4,7 +4,6 @@ error: struct `T` is never constructed
 LL | struct T;
    |        ^
    |
-   = note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis
 note: the lint level is defined here
   --> $DIR/unused-struct-derive-default.rs:1:9
    |
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
index 83f1ee6a77e..7cbe8e0943a 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs
@@ -1,5 +1,6 @@
 //@ edition: 2024
 //@ compile-flags: -Zunstable-options
+// gate-test-ref_pat_eat_one_layer_2024_structural
 
 pub fn main() {
     if let Some(Some(&x)) = &Some(&Some(0)) {
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
index 132fe421a18..b3ea60252ac 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:6:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:11:23
    |
 LL |         let _: &u32 = x;
    |                ----   ^ expected `&u32`, found integer
@@ -27,7 +27,7 @@ LL |         let _: &u32 = &x;
    |                       +
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:14:23
    |
 LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
    |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
@@ -43,7 +43,7 @@ LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
    |
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:18:17
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -64,7 +64,7 @@ LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^
@@ -74,7 +74,7 @@ LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:26:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -89,7 +89,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:30:27
    |
 LL |     if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
    |                           ^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -104,7 +104,7 @@ LL |     if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
    |                           ~
 
 error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -114,7 +114,7 @@ LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23
+  --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
index d28567f2859..afea249ffef 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs
@@ -1,37 +1,15 @@
+//@ run-pass
 //@ edition: 2021
+//@ revisions: classic structural both
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
+
 pub fn main() {
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&x)) = &Some(Some(&0)) {
+    if let &Some(Some(x)) = &Some(&mut Some(0)) {
         let _: &u32 = x;
-        //~^ ERROR: mismatched types
-    }
-    if let Some(Some(&&x)) = &Some(Some(&0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(&Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
-    }
-    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
-        let _: u32 = x;
     }
-    if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
-        //~^ ERROR: mismatched types
+    if let Some(&x) = Some(&mut 0) {
         let _: u32 = x;
     }
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs
new file mode 100644
index 00000000000..d28567f2859
--- /dev/null
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs
@@ -0,0 +1,37 @@
+//@ edition: 2021
+#![allow(incomplete_features)]
+#![feature(ref_pat_eat_one_layer_2024)]
+pub fn main() {
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&x)) = &Some(Some(&0)) {
+        let _: &u32 = x;
+        //~^ ERROR: mismatched types
+    }
+    if let Some(Some(&&x)) = &Some(Some(&0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&Some(x)) = &Some(Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+    if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
+        //~^ ERROR: mismatched types
+        let _: u32 = x;
+    }
+}
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr
index 28706f89c06..1a921234ea0 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -14,7 +14,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23
    |
 LL |         let _: &u32 = x;
    |                ----   ^ expected `&u32`, found integer
@@ -27,7 +27,7 @@ LL |         let _: &u32 = &x;
    |                       +
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23
    |
 LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
    |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
@@ -43,7 +43,7 @@ LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
    |
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -54,7 +54,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -64,7 +64,7 @@ LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^
@@ -74,7 +74,7 @@ LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22
    |
 LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
    |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -89,7 +89,7 @@ LL |     if let Some(Some(x)) = &Some(&Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27
    |
 LL |     if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
    |                           ^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
@@ -104,7 +104,7 @@ LL |     if let Some(&mut Some(x)) = &Some(&mut Some(0)) {
    |                           ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
@@ -114,7 +114,7 @@ LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23
+  --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23
    |
 LL |     if let Some(&Some(&mut x)) = &mut Some(&Some(0)) {
    |                       ^^^^^^
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
index 829b7f86e26..c6a699d2ff8 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
@@ -1,8 +1,10 @@
 //@ run-pass
 //@ edition: 2024
 //@ compile-flags: -Zunstable-options
+//@ revisions: classic structural both
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(Some(&x)) = &Some(&Some(0)) {
@@ -53,4 +55,35 @@ pub fn main() {
     if let Some(&Some(x)) = &mut Some(Some(0)) {
         let _: u32 = x;
     }
+    #[cfg(any(classic, both))]
+    if let Some(&mut x) = &mut Some(&0) {
+        let _: &u32 = x;
+    }
+    #[cfg(any(structural, both))]
+    if let Some(&mut x) = &Some(&mut 0) {
+        let _: &u32 = x;
+    }
+
+    fn generic<R: Ref>() -> (R, bool) {
+        R::meow()
+    }
+
+    trait Ref: Sized {
+        fn meow() -> (Self, bool);
+    }
+
+    impl Ref for &'static [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&[], false)
+        }
+    }
+
+    impl Ref for &'static mut [(); 0] {
+        fn meow() -> (Self, bool) {
+            (&mut [], true)
+        }
+    }
+
+    let (&_, b) = generic();
+    assert!(!b);
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
new file mode 100644
index 00000000000..0215df98ea1
--- /dev/null
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr
@@ -0,0 +1,169 @@
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
+   |
+LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
+   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note:      expected reference `&Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
+   |
+LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
+   |
+LL |         let _: &mut u32 = x;
+   |                --------   ^ types differ in mutability
+   |                |
+   |                expected due to this
+   |
+   = note: expected mutable reference `&mut u32`
+                      found reference `&{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
+   |
+LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
+   |
+LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
+   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
+   |                             |
+   |                             expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
+   |
+LL |     let &mut _ = &&0;
+   |         ^^^^^^   --- this expression has type `&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
+   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
+   |
+LL |     let &mut _ = &&mut 0;
+   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
+   |
+LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 15 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
index 26317e43d02..9428b32c4af 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr
@@ -1,27 +1,29 @@
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
    |                 ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(&_)) = &Some(&Some(0)) {
    |                 ~
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
    |
 LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
    |                       ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
    |                       ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
    |
 LL |         let _: &mut u32 = x;
    |                --------   ^ types differ in mutability
@@ -31,52 +33,56 @@ LL |         let _: &mut u32 = x;
    = note: expected mutable reference `&mut u32`
                       found reference `&{integer}`
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
    |
 LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
    |                       ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(&_)) = &mut Some(&Some(0)) {
    |                       ~
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
    |
 LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
    |                             ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
    |                             ~
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ~
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
    |                 ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
    |
 LL |     let &mut _ = &&0;
    |         ^^^^^^   --- this expression has type `&&{integer}`
@@ -87,7 +93,7 @@ LL |     let &mut _ = &&0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
@@ -97,30 +103,32 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
            found mutable reference `&mut _`
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:38:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
    |                 ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
    |                 ~
 
-error: cannot match inherited `&` with `&mut` pattern
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:42:22
    |
 LL |     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
    |                      ^^^^^
    |
+   = note: cannot match inherited `&` with `&mut` pattern
 help: replace this `&mut` pattern with `&`
    |
 LL |     if let Some(Some(&x)) = &Some(Some(&mut 0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
    |
 LL |     let &mut _ = &&mut 0;
    |         ^^^^^^   ------- this expression has type `&&mut {integer}`
@@ -131,7 +139,7 @@ LL |     let &mut _ = &&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
    |
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
    |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
@@ -142,7 +150,7 @@ LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
    |
 LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
    |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
@@ -153,7 +161,7 @@ LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
            found mutable reference `&mut _`
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
    |
 LL |     let Foo(mut a) = &Foo(0);
    |             ^^^^
@@ -163,7 +171,7 @@ LL |     let Foo(mut a) = &Foo(0);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: binding cannot be both mutable and by-reference
-  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
    |
 LL |     let Foo(mut a) = &mut Foo(0);
    |             ^^^^
@@ -172,7 +180,20 @@ LL |     let Foo(mut a) = &mut Foo(0);
    = help: add `#![feature(mut_ref)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 16 previous errors
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 17 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
index 40e8293e241..d23e9c8083d 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
@@ -1,30 +1,32 @@
 //@ edition: 2024
 //@ compile-flags: -Zunstable-options
+//@ revisions: classic structural both
 #![allow(incomplete_features)]
-#![feature(ref_pat_eat_one_layer_2024)]
+#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))]
+#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
     if let Some(&Some(x)) = &mut Some(&Some(0)) {
         let _: &mut u32 = x;
         //~^ ERROR: mismatched types
     }
     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
     if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
     if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //~^ ERROR: mismatched types
     }
 
     let &mut _ = &&0;
@@ -34,11 +36,11 @@ pub fn main() {
     //~^ ERROR: mismatched types
 
     if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //[classic]~^ ERROR: mismatched types
     }
 
     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
-        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+        //[classic]~^ ERROR: mismatched types
     }
 
     let &mut _ = &&mut 0;
@@ -50,6 +52,10 @@ pub fn main() {
     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
     //~^ ERROR: mismatched types
 
+    if let Some(&mut _) = &mut Some(&0) {
+        //[structural]~^ ERROR
+    }
+
     struct Foo(u8);
 
     let Foo(mut a) = &Foo(0);
@@ -59,4 +65,20 @@ pub fn main() {
     let Foo(mut a) = &mut Foo(0);
     //~^ ERROR: binding cannot be both mutable and by-reference
     a = &mut 42;
+
+    fn generic<R: Ref>() -> R {
+        R::meow()
+    }
+
+    trait Ref: Sized {
+        fn meow() -> Self;
+    }
+
+    impl Ref for &'static mut [(); 0] {
+        fn meow() -> Self {
+            &mut []
+        }
+    }
+
+    let &_ = generic(); //~ERROR: the trait bound `&_: main::Ref` is not satisfied [E0277]
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
new file mode 100644
index 00000000000..56dad605030
--- /dev/null
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr
@@ -0,0 +1,180 @@
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17
+   |
+LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
+   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note:      expected reference `&Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23
+   |
+LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27
+   |
+LL |         let _: &mut u32 = x;
+   |                --------   ^ types differ in mutability
+   |                |
+   |                expected due to this
+   |
+   = note: expected mutable reference `&mut u32`
+                      found reference `&{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23
+   |
+LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
+   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29
+   |
+LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
+   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
+   |                             |
+   |                             expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17
+   |
+LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&mut _`
+   |
+   = note:           expected enum `Option<{integer}>`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9
+   |
+LL |     let &mut _ = &&0;
+   |         ^^^^^^   --- this expression has type `&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
+   |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9
+   |
+LL |     let &mut _ = &&mut 0;
+   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14
+   |
+LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:17
+   |
+LL |     if let Some(&mut _) = &mut Some(&0) {
+   |                 ^^^^^^    ------------- this expression has type `&mut Option<&{integer}>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note:      expected reference `&{integer}`
+           found mutable reference `&mut _`
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0277]: the trait bound `&_: main::Ref` is not satisfied
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:83:14
+   |
+LL |     let &_ = generic();
+   |              ^^^^^^^^^ the trait `main::Ref` is not implemented for `&_`
+   |
+   = help: the trait `main::Ref` is implemented for `&'static mut [(); 0]`
+note: required by a bound in `generic`
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:69:19
+   |
+LL |     fn generic<R: Ref>() -> R {
+   |                   ^^^ required by this bound in `generic`
+
+error: aborting due to 16 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/method-output-diff-issue-127263.rs b/tests/ui/method-output-diff-issue-127263.rs
new file mode 100644
index 00000000000..85a903e2453
--- /dev/null
+++ b/tests/ui/method-output-diff-issue-127263.rs
@@ -0,0 +1,8 @@
+fn bar() {}
+fn foo(x: i32) -> u32 {
+    0
+}
+fn main() {
+    let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308]
+    let f: fn(i32) = foo; //~ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/method-output-diff-issue-127263.stderr b/tests/ui/method-output-diff-issue-127263.stderr
new file mode 100644
index 00000000000..35b86114f16
--- /dev/null
+++ b/tests/ui/method-output-diff-issue-127263.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+  --> $DIR/method-output-diff-issue-127263.rs:6:26
+   |
+LL |     let b: fn() -> u32 = bar;
+   |            -----------   ^^^ expected fn pointer, found fn item
+   |            |
+   |            expected due to this
+   |
+   = note: expected fn pointer `fn() -> u32`
+                 found fn item `fn() -> () {bar}`
+
+error[E0308]: mismatched types
+  --> $DIR/method-output-diff-issue-127263.rs:7:22
+   |
+LL |     let f: fn(i32) = foo;
+   |            -------   ^^^ expected fn pointer, found fn item
+   |            |
+   |            expected due to this
+   |
+   = note: expected fn pointer `fn(_) -> ()`
+                 found fn item `fn(_) -> u32 {foo}`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index 5a76449e9f9..0855a17b333 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -2,16 +2,18 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:13:7
    |
 LL |     x.zero(0)
-   |       ^^^^ -
-   |            |
-   |            unexpected argument of type `{integer}`
-   |            help: remove the extra argument
+   |       ^^^^ - unexpected argument of type `{integer}`
    |
 note: method defined here
   --> $DIR/method-call-err-msg.rs:5:8
    |
 LL |     fn zero(self) -> Foo { self }
    |        ^^^^
+help: remove the extra argument
+   |
+LL -     x.zero(0)
+LL +     x.zero()
+   |
 
 error[E0061]: this method takes 1 argument but 0 arguments were supplied
   --> $DIR/method-call-err-msg.rs:14:7
diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr
index d0bd5b46cf5..2559d448749 100644
--- a/tests/ui/mismatched_types/E0053.stderr
+++ b/tests/ui/mismatched_types/E0053.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/E0053.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/E0053.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/E0053.rs:11:12
    |
 LL |     fn bar(&mut self) { }
-   |            ^^^^^^^^^
-   |            |
-   |            types differ in mutability
-   |            help: change the self-receiver type to match the trait: `&self`
+   |            ^^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/E0053.rs:3:12
@@ -31,6 +29,10 @@ LL |     fn bar(&self);
    |            ^^^^^
    = note: expected signature `fn(&Bar)`
               found signature `fn(&mut Bar)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn bar(&self) { }
+   |            ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr
index b93ce4a8674..bd446b3d78c 100644
--- a/tests/ui/mismatched_types/issue-112036.stderr
+++ b/tests/ui/mismatched_types/issue-112036.stderr
@@ -2,13 +2,14 @@ error[E0053]: method `drop` has an incompatible type for trait
   --> $DIR/issue-112036.rs:4:13
    |
 LL |     fn drop(self) {}
-   |             ^^^^
-   |             |
-   |             expected `&mut Foo`, found `Foo`
-   |             help: change the self-receiver type to match the trait: `&mut self`
+   |             ^^^^ expected `&mut Foo`, found `Foo`
    |
    = note: expected signature `fn(&mut Foo)`
               found signature `fn(Foo)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn drop(&mut self) {}
+   |             ~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr
index 4886fa30e89..2a266d40e77 100644
--- a/tests/ui/mismatched_types/issue-13033.stderr
+++ b/tests/ui/mismatched_types/issue-13033.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-13033.rs:8:30
    |
 LL |     fn bar(&mut self, other: &dyn Foo) {}
-   |                              ^^^^^^^^
-   |                              |
-   |                              types differ in mutability
-   |                              help: change the parameter type to match the trait: `&mut dyn Foo`
+   |                              ^^^^^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/issue-13033.rs:2:30
@@ -14,6 +11,10 @@ LL |     fn bar(&mut self, other: &mut dyn Foo);
    |                              ^^^^^^^^^^^^
    = note: expected signature `fn(&mut Baz, &mut dyn Foo)`
               found signature `fn(&mut Baz, &dyn Foo)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, other: &mut dyn Foo) {}
+   |                              ~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 6e7bf5eb46d..2e544a62223 100644
--- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:9:15
    |
 LL |     fn foo(x: i16) { }
-   |               ^^^
-   |               |
-   |               expected `u16`, found `i16`
-   |               help: change the parameter type to match the trait: `u16`
+   |               ^^^ expected `u16`, found `i16`
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(x: u16);
    |               ^^^
    = note: expected signature `fn(u16)`
               found signature `fn(i16)`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(x: u16) { }
+   |               ~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:10:28
    |
 LL |     fn bar(&mut self, bar: &Bar) { }
-   |                            ^^^^
-   |                            |
-   |                            types differ in mutability
-   |                            help: change the parameter type to match the trait: `&mut Bar`
+   |                            ^^^^ types differ in mutability
    |
 note: type in trait
   --> $DIR/trait-impl-fn-incompatibility.rs:3:28
@@ -31,6 +29,10 @@ LL |     fn bar(&mut self, bar: &mut Bar);
    |                            ^^^^^^^^
    = note: expected signature `fn(&mut Bar, &mut Bar)`
               found signature `fn(&mut Bar, &Bar)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(&mut self, bar: &mut Bar) { }
+   |                            ~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
index 812f7a0692f..4fea52fec6e 100644
--- a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
+++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
@@ -5,7 +5,7 @@ LL | fn panic(info: PanicInfo) -> () {}
    |                ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>`
    |
    = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
-              found signature `for<'a> fn(PanicInfo<'a>)`
+              found signature `for<'a> fn(PanicInfo<'a>) -> ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-105366.fixed b/tests/ui/parser/issues/issue-105366.fixed
index 7157b647524..95419dc07f2 100644
--- a/tests/ui/parser/issues/issue-105366.fixed
+++ b/tests/ui/parser/issues/issue-105366.fixed
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct Foo;
 
 impl From<i32> for Foo {
diff --git a/tests/ui/parser/issues/issue-105366.rs b/tests/ui/parser/issues/issue-105366.rs
index dc3cb8b343d..3278b737991 100644
--- a/tests/ui/parser/issues/issue-105366.rs
+++ b/tests/ui/parser/issues/issue-105366.rs
@@ -1,5 +1,6 @@
 //@ run-rustfix
 
+#[allow(dead_code)]
 struct Foo;
 
 fn From<i32> for Foo {
diff --git a/tests/ui/parser/issues/issue-105366.stderr b/tests/ui/parser/issues/issue-105366.stderr
index 18c04dfaf20..195305a2ec8 100644
--- a/tests/ui/parser/issues/issue-105366.stderr
+++ b/tests/ui/parser/issues/issue-105366.stderr
@@ -1,5 +1,5 @@
 error: you might have meant to write `impl` instead of `fn`
-  --> $DIR/issue-105366.rs:5:1
+  --> $DIR/issue-105366.rs:6:1
    |
 LL | fn From<i32> for Foo {
    | ^^
diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr
index 1694d514f42..f15a0ae6138 100644
--- a/tests/ui/range/issue-54505-no-std.stderr
+++ b/tests/ui/range/issue-54505-no-std.stderr
@@ -7,7 +7,7 @@ LL |     take_range(0..1);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `Range<{integer}>`
+                 found struct `core::ops::Range<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
@@ -27,7 +27,7 @@ LL |     take_range(1..);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeFrom<{integer}>`
+                 found struct `core::ops::RangeFrom<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
@@ -67,7 +67,7 @@ LL |     take_range(0..=1);
    |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
-                 found struct `RangeInclusive<{integer}>`
+                 found struct `core::ops::RangeInclusive<{integer}>`
 note: function defined here
   --> $DIR/issue-54505-no-std.rs:25:4
    |
diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr
index e3a5d4edcf1..d0583966459 100644
--- a/tests/ui/resolve/resolve-primitive-fallback.stderr
+++ b/tests/ui/resolve/resolve-primitive-fallback.stderr
@@ -24,13 +24,15 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/resolve-primitive-fallback.rs:3:5
    |
 LL |     std::mem::size_of(u16);
-   |     ^^^^^^^^^^^^^^^^^ ---
-   |                       |
-   |                       unexpected argument
-   |                       help: remove the extra argument
+   |     ^^^^^^^^^^^^^^^^^ --- unexpected argument
    |
 note: function defined here
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     std::mem::size_of(u16);
+LL +     std::mem::size_of();
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr
index f0dea66f612..89c67719b5a 100644
--- a/tests/ui/span/issue-34264.stderr
+++ b/tests/ui/span/issue-34264.stderr
@@ -54,16 +54,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:7:5
    |
 LL |     foo(Some(42), 2, "");
-   |     ^^^            ----
-   |                    | |
-   |                    | unexpected argument of type `&'static str`
-   |                    help: remove the extra argument
+   |     ^^^              -- unexpected argument of type `&'static str`
    |
 note: function defined here
   --> $DIR/issue-34264.rs:1:4
    |
 LL | fn foo(Option<i32>, String) {}
    |    ^^^ -----------  ------
+help: remove the extra argument
+   |
+LL -     foo(Some(42), 2, "");
+LL +     foo(Some(42), 2);
+   |
 
 error[E0308]: mismatched types
   --> $DIR/issue-34264.rs:8:13
@@ -83,16 +85,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:10:5
    |
 LL |     bar(1, 2, 3);
-   |     ^^^     ---
-   |             | |
-   |             | unexpected argument of type `{integer}`
-   |             help: remove the extra argument
+   |     ^^^       - unexpected argument of type `{integer}`
    |
 note: function defined here
   --> $DIR/issue-34264.rs:3:4
    |
 LL | fn bar(x, y: usize) {}
    |    ^^^ -  --------
+help: remove the extra argument
+   |
+LL -     bar(1, 2, 3);
+LL +     bar(1, 2);
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/traits/impl-method-mismatch.stderr b/tests/ui/traits/impl-method-mismatch.stderr
index 77d542c729a..db457b77a23 100644
--- a/tests/ui/traits/impl-method-mismatch.stderr
+++ b/tests/ui/traits/impl-method-mismatch.stderr
@@ -10,7 +10,7 @@ note: type in trait
 LL |     fn jumbo(&self, x: &usize) -> usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected signature `fn(&_, &_) -> usize`
-              found signature `unsafe fn(&_, &_)`
+              found signature `unsafe fn(&_, &_) -> ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr
index 6d985bdeaf8..503f9cee246 100644
--- a/tests/ui/traits/issue-35869.stderr
+++ b/tests/ui/traits/issue-35869.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait
   --> $DIR/issue-35869.rs:11:15
    |
 LL |     fn foo(_: fn(u16) -> ()) {}
-   |               ^^^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `fn(u8)`
+   |               ^^^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:2:15
@@ -14,15 +11,16 @@ LL |     fn foo(_: fn(u8) -> ());
    |               ^^^^^^^^^^^^
    = note: expected signature `fn(fn(u8))`
               found signature `fn(fn(u16))`
+help: change the parameter type to match the trait
+   |
+LL |     fn foo(_: fn(u8)) {}
+   |               ~~~~~~
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/issue-35869.rs:13:15
    |
 LL |     fn bar(_: Option<u16>) {}
-   |               ^^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `Option<u8>`
+   |               ^^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:3:15
@@ -31,15 +29,16 @@ LL |     fn bar(_: Option<u8>);
    |               ^^^^^^^^^^
    = note: expected signature `fn(Option<u8>)`
               found signature `fn(Option<u16>)`
+help: change the parameter type to match the trait
+   |
+LL |     fn bar(_: Option<u8>) {}
+   |               ~~~~~~~~~~
 
 error[E0053]: method `baz` has an incompatible type for trait
   --> $DIR/issue-35869.rs:15:15
    |
 LL |     fn baz(_: (u16, u16)) {}
-   |               ^^^^^^^^^^
-   |               |
-   |               expected `u8`, found `u16`
-   |               help: change the parameter type to match the trait: `(u8, u16)`
+   |               ^^^^^^^^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:4:15
@@ -48,15 +47,16 @@ LL |     fn baz(_: (u8, u16));
    |               ^^^^^^^^^
    = note: expected signature `fn((u8, _))`
               found signature `fn((u16, _))`
+help: change the parameter type to match the trait
+   |
+LL |     fn baz(_: (u8, u16)) {}
+   |               ~~~~~~~~~
 
 error[E0053]: method `qux` has an incompatible type for trait
   --> $DIR/issue-35869.rs:17:17
    |
 LL |     fn qux() -> u16 { 5u16 }
-   |                 ^^^
-   |                 |
-   |                 expected `u8`, found `u16`
-   |                 help: change the output type to match the trait: `u8`
+   |                 ^^^ expected `u8`, found `u16`
    |
 note: type in trait
   --> $DIR/issue-35869.rs:5:17
@@ -65,6 +65,10 @@ LL |     fn qux() -> u8;
    |                 ^^
    = note: expected signature `fn() -> u8`
               found signature `fn() -> u16`
+help: change the output type to match the trait
+   |
+LL |     fn qux() -> u8 { 5u16 }
+   |                 ~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr
index 91162cbc123..e30b61622ae 100644
--- a/tests/ui/traits/wrong-mul-method-signature.stderr
+++ b/tests/ui/traits/wrong-mul-method-signature.stderr
@@ -2,37 +2,40 @@ error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:16:21
    |
 LL |     fn mul(self, s: &f64) -> Vec1 {
-   |                     ^^^^
-   |                     |
-   |                     expected `f64`, found `&f64`
-   |                     help: change the parameter type to match the trait: `f64`
+   |                     ^^^^ expected `f64`, found `&f64`
    |
    = note: expected signature `fn(Vec1, _) -> Vec1`
               found signature `fn(Vec1, &_) -> Vec1`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> Vec1 {
+   |                     ~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:33:21
    |
 LL |     fn mul(self, s: f64) -> Vec2 {
-   |                     ^^^
-   |                     |
-   |                     expected `Vec2`, found `f64`
-   |                     help: change the parameter type to match the trait: `Vec2`
+   |                     ^^^ expected `Vec2`, found `f64`
    |
    = note: expected signature `fn(Vec2, Vec2) -> f64`
               found signature `fn(Vec2, f64) -> Vec2`
+help: change the parameter type to match the trait
+   |
+LL |     fn mul(self, s: Vec2) -> Vec2 {
+   |                     ~~~~
 
 error[E0053]: method `mul` has an incompatible type for trait
   --> $DIR/wrong-mul-method-signature.rs:52:29
    |
 LL |     fn mul(self, s: f64) -> f64 {
-   |                             ^^^
-   |                             |
-   |                             expected `i32`, found `f64`
-   |                             help: change the output type to match the trait: `i32`
+   |                             ^^^ expected `i32`, found `f64`
    |
    = note: expected signature `fn(Vec3, _) -> i32`
               found signature `fn(Vec3, _) -> f64`
+help: change the output type to match the trait
+   |
+LL |     fn mul(self, s: f64) -> i32 {
+   |                             ~~~
 
 error[E0308]: mismatched types
   --> $DIR/wrong-mul-method-signature.rs:63:45
diff --git a/tests/ui/tuple/wrong_argument_ice-4.stderr b/tests/ui/tuple/wrong_argument_ice-4.stderr
index 3c7d6699be2..10191faf7bf 100644
--- a/tests/ui/tuple/wrong_argument_ice-4.stderr
+++ b/tests/ui/tuple/wrong_argument_ice-4.stderr
@@ -6,16 +6,21 @@ LL |       (|| {})(|| {
 LL | |
 LL | |         let b = 1;
 LL | |     });
-   | |     -
-   | |     |
-   | |_____unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}`
-   |       help: remove the extra argument
+   | |_____- unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}`
    |
 note: closure defined here
   --> $DIR/wrong_argument_ice-4.rs:2:6
    |
 LL |     (|| {})(|| {
    |      ^^
+help: remove the extra argument
+   |
+LL -     (|| {})(|| {
+LL -
+LL -         let b = 1;
+LL -     });
+LL +     (|| {})();
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index f567b01d29a..5b331c5660d 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -5,10 +5,7 @@ LL | type MyPrivate = impl Sized;
    |                  ---------- the found opaque type
 LL | impl Trait for u32 {
 LL |     fn dont_define_this(private: MyPrivate) {
-   |                                  ^^^^^^^^^
-   |                                  |
-   |                                  expected `Private`, found opaque type
-   |                                  help: change the parameter type to match the trait: `Private`
+   |                                  ^^^^^^^^^ expected `Private`, found opaque type
    |
 note: type in trait
   --> $DIR/unnameable_type.rs:10:39
@@ -17,6 +14,10 @@ LL |         fn dont_define_this(_private: Private) {}
    |                                       ^^^^^^^
    = note: expected signature `fn(Private)`
               found signature `fn(MyPrivate)`
+help: change the parameter type to match the trait
+   |
+LL |     fn dont_define_this(private: Private) {
+   |                                  ~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr
index efa917334bf..224ff6e7404 100644
--- a/tests/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr
@@ -11,13 +11,15 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/type-ascription-instead-of-initializer.rs:2:12
    |
 LL |     let x: Vec::with_capacity(10, 20);
-   |            ^^^^^^^^^^^^^^^^^^   ----
-   |                                 | |
-   |                                 | unexpected argument of type `{integer}`
-   |                                 help: remove the extra argument
+   |            ^^^^^^^^^^^^^^^^^^     -- unexpected argument of type `{integer}`
    |
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     let x: Vec::with_capacity(10, 20);
+LL +     let x: Vec::with_capacity(10);
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr
index 322bf349f92..59de00a58bb 100644
--- a/tests/ui/typeck/mismatched-map-under-self.stderr
+++ b/tests/ui/typeck/mismatched-map-under-self.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `values` has an incompatible type for trait
   --> $DIR/mismatched-map-under-self.rs:10:15
    |
 LL |     fn values(self) -> Self::Values {
-   |               ^^^^
-   |               |
-   |               expected `&Option<T>`, found `Option<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |               ^^^^ expected `&Option<T>`, found `Option<T>`
    |
 note: type in trait
   --> $DIR/mismatched-map-under-self.rs:4:15
@@ -14,6 +11,10 @@ LL |     fn values(&self) -> Self::Values;
    |               ^^^^^
    = note: expected signature `fn(&Option<_>)`
               found signature `fn(Option<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn values(&self) -> Self::Values {
+   |               ~~~~~
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/mismatched-map-under-self.rs:12:18
diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr
index b615d9fb45c..2912977a461 100644
--- a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr
+++ b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
   --> $DIR/ptr-null-mutability-suggestions.rs:9:24
    |
 LL |     expecting_null_mut(ptr::null());
-   |     ------------------ ^^^^^^^^^^^
-   |     |                  |
-   |     |                  types differ in mutability
-   |     |                  help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()`
+   |     ------------------ ^^^^^^^^^^^ types differ in mutability
+   |     |
    |     arguments to this function are incorrect
    |
    = note: expected raw pointer `*mut u8`
@@ -15,6 +13,10 @@ note: function defined here
    |
 LL | fn expecting_null_mut(_: *mut u8) {}
    |    ^^^^^^^^^^^^^^^^^^ ----------
+help: consider using `core::ptr::null_mut` instead
+   |
+LL |     expecting_null_mut(core::ptr::null_mut());
+   |                        ~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr
index 9557c41457d..4bab2959651 100644
--- a/tests/ui/typeck/remove-extra-argument.stderr
+++ b/tests/ui/typeck/remove-extra-argument.stderr
@@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/remove-extra-argument.rs:6:5
    |
 LL |     l(vec![], vec![])
-   |     ^       --------
-   |             | |
-   |             | unexpected argument of type `Vec<_>`
-   |             help: remove the extra argument
+   |     ^         ------ unexpected argument of type `Vec<_>`
    |
 note: function defined here
   --> $DIR/remove-extra-argument.rs:3:4
    |
 LL | fn l(_a: Vec<u8>) {}
    |    ^ -----------
+help: remove the extra argument
+   |
+LL -     l(vec![], vec![])
+LL +     l(vec![])
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr
index 57cbd1d2005..d005eca841e 100644
--- a/tests/ui/typeck/struct-enum-wrong-args.stderr
+++ b/tests/ui/typeck/struct-enum-wrong-args.stderr
@@ -2,13 +2,15 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:6:13
    |
 LL |     let _ = Some(3, 2);
-   |             ^^^^  ---
-   |                   | |
-   |                   | unexpected argument of type `{integer}`
-   |                   help: remove the extra argument
+   |             ^^^^    - unexpected argument of type `{integer}`
    |
 note: tuple variant defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
+help: remove the extra argument
+   |
+LL -     let _ = Some(3, 2);
+LL +     let _ = Some(3);
+   |
 
 error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:7:13
@@ -59,16 +61,18 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
    |
 LL |     let _ = Wrapper(5, 2);
-   |             ^^^^^^^  ---
-   |                      | |
-   |                      | unexpected argument of type `{integer}`
-   |                      help: remove the extra argument
+   |             ^^^^^^^    - unexpected argument of type `{integer}`
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:2:8
    |
 LL | struct Wrapper(i32);
    |        ^^^^^^^
+help: remove the extra argument
+   |
+LL -     let _ = Wrapper(5, 2);
+LL +     let _ = Wrapper(5);
+   |
 
 error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:11:13
@@ -106,16 +110,18 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
    |
 LL |     let _ = DoubleWrapper(5, 2, 7);
-   |             ^^^^^^^^^^^^^     ---
-   |                               | |
-   |                               | unexpected argument of type `{integer}`
-   |                               help: remove the extra argument
+   |             ^^^^^^^^^^^^^       - unexpected argument of type `{integer}`
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
    |
 LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL -     let _ = DoubleWrapper(5, 2, 7);
+LL +     let _ = DoubleWrapper(5, 2);
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index c48d094daea..2a8c4edbdb5 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -2,10 +2,7 @@ error[E0053]: method `dummy2` has an incompatible type for trait
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
-   |               ------^^^^^^^
-   |               |     |
-   |               |     expected `&'a Bar<T>`, found `Bar<T>`
-   |               help: change the self-receiver type to match the trait: `&self`
+   |                     ^^^^^^^ expected `&'a Bar<T>`, found `Bar<T>`
    |
 note: type in trait
   --> $DIR/ufcs-explicit-self-bad.rs:31:15
@@ -14,6 +11,10 @@ LL |     fn dummy2(&self);
    |               ^^^^^
    = note: expected signature `fn(&&'a Bar<_>)`
               found signature `fn(&Bar<_>)`
+help: change the self-receiver type to match the trait
+   |
+LL |     fn dummy2(&self) {}
+   |               ~~~~~
 
 error[E0307]: invalid `self` parameter type: `isize`
   --> $DIR/ufcs-explicit-self-bad.rs:8:18
diff --git a/tests/ui/unsigned-literal-negation.stderr b/tests/ui/unsigned-literal-negation.stderr
index 0aaa8c3b72f..b0a730477a1 100644
--- a/tests/ui/unsigned-literal-negation.stderr
+++ b/tests/ui/unsigned-literal-negation.stderr
@@ -2,34 +2,37 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
   --> $DIR/unsigned-literal-negation.rs:2:13
    |
 LL |     let x = -1 as usize;
-   |             ^^
-   |             |
-   |             cannot apply unary operator `-`
-   |             help: you may have meant the maximum value of `usize`: `usize::MAX`
+   |             ^^ cannot apply unary operator `-`
    |
    = note: unsigned values cannot be negated
+help: you may have meant the maximum value of `usize`
+   |
+LL |     let x = usize::MAX;
+   |             ~~~~~~~~~~
 
 error[E0600]: cannot apply unary operator `-` to type `usize`
   --> $DIR/unsigned-literal-negation.rs:3:13
    |
 LL |     let x = (-1) as usize;
-   |             ^^^^
-   |             |
-   |             cannot apply unary operator `-`
-   |             help: you may have meant the maximum value of `usize`: `usize::MAX`
+   |             ^^^^ cannot apply unary operator `-`
    |
    = note: unsigned values cannot be negated
+help: you may have meant the maximum value of `usize`
+   |
+LL |     let x = usize::MAX;
+   |             ~~~~~~~~~~
 
 error[E0600]: cannot apply unary operator `-` to type `u32`
   --> $DIR/unsigned-literal-negation.rs:4:18
    |
 LL |     let x: u32 = -1;
-   |                  ^^
-   |                  |
-   |                  cannot apply unary operator `-`
-   |                  help: you may have meant the maximum value of `u32`: `u32::MAX`
+   |                  ^^ cannot apply unary operator `-`
    |
    = note: unsigned values cannot be negated
+help: you may have meant the maximum value of `u32`
+   |
+LL |     let x: u32 = u32::MAX;
+   |                  ~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index 8ae454d412a..746a6630052 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -952,7 +952,6 @@ bootstrap = [
     "@Mark-Simulacrum",
     "@albertlarsan68",
     "@onur-ozkan",
-    "@clubby789",
     "@kobzol",
 ]
 infra-ci = [