about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock21
-rw-r--r--compiler/rustc_ast/src/expand/autodiff_attrs.rs40
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder/autodiff.rs38
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs48
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/check_consts/resolver.rs24
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs25
-rw-r--r--compiler/rustc_index/src/slice.rs13
-rw-r--r--compiler/rustc_middle/src/hir/place.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/match_pair.rs25
-rw-r--r--compiler/rustc_mir_transform/src/post_analysis_normalize.rs28
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs11
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/autodiff.rs32
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs24
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs163
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs2
-rw-r--r--compiler/rustc_session/src/config.rs37
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/select.rs2
-rw-r--r--compiler/rustc_type_ir/src/solve/inspect.rs10
-rw-r--r--diff0
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/core/src/hint.rs30
-rw-r--r--library/core/src/intrinsics/mod.rs2
-rw-r--r--library/core/src/num/f128.rs18
-rw-r--r--library/core/src/num/f16.rs18
-rw-r--r--library/core/src/num/f32.rs18
-rw-r--r--library/core/src/num/f64.rs18
-rw-r--r--library/coretests/tests/hint.rs23
-rw-r--r--library/coretests/tests/lib.rs2
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs4
-rw-r--r--src/build_helper/src/fs/mod.rs56
-rw-r--r--src/build_helper/src/fs/tests.rs2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/best-practices.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md3
-rw-r--r--src/librustdoc/clean/inline.rs43
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs5
-rw-r--r--src/tools/compiletest/src/directive-list.rs1
-rw-r--r--src/tools/compiletest/src/header/cfg.rs4
-rw-r--r--src/tools/compiletest/src/header/tests.rs6
-rw-r--r--src/tools/compiletest/src/runtest.rs31
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs4
-rw-r--r--src/tools/miri/tests/pass/tls/tls_leak_main_thread_allowed.rs2
-rw-r--r--src/tools/opt-dist/src/environment.rs5
-rw-r--r--src/tools/opt-dist/src/main.rs10
-rw-r--r--src/tools/run-make-support/Cargo.toml4
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock4
-rw-r--r--src/tools/tidy/src/deps.rs3
-rw-r--r--tests/assembly/cstring-merging.rs8
-rw-r--r--tests/codegen/autodiffv2.rs113
-rw-r--r--tests/codegen/issues/issue-101082.rs12
-rw-r--r--tests/codegen/remap_path_prefix/aux_mod.rs2
-rw-r--r--tests/crashes/100618.rs12
-rw-r--r--tests/crashes/115994.rs17
-rw-r--r--tests/crashes/121538.rs30
-rw-r--r--tests/debuginfo/drop-locations.rs4
-rw-r--r--tests/debuginfo/recursive-enum.rs17
-rw-r--r--tests/debuginfo/recursive-type-with-gat.rs (renamed from tests/crashes/107362.rs)1
-rw-r--r--tests/run-make/broken-pipe-no-ice/rmake.rs6
-rw-r--r--tests/run-make/print-request-help-stable-unstable/help-diff.diff7
-rw-r--r--tests/run-make/print-request-help-stable-unstable/rmake.rs33
-rw-r--r--tests/run-make/print-request-help-stable-unstable/stable-invalid-print-request-help.err5
-rw-r--r--tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err5
-rw-r--r--tests/rustdoc/auxiliary/ext-trait-aliases.rs13
-rw-r--r--tests/rustdoc/auxiliary/trait-alias-mention.rs3
-rw-r--r--tests/rustdoc/trait-alias-mention.rs10
-rw-r--r--tests/rustdoc/trait-aliases.rs82
-rw-r--r--tests/rustdoc/trait_alias.rs26
-rw-r--r--tests/ui/borrowck/move-error-snippets-ext.rs2
-rw-r--r--tests/ui/codemap_tests/two_files_data.rs2
-rw-r--r--tests/ui/conditional-compilation/module_with_cfg.rs2
-rw-r--r--tests/ui/cross/cross-file-errors/underscore.rs2
-rw-r--r--tests/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs2
-rw-r--r--tests/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs2
-rw-r--r--tests/ui/directory_ownership/mod_file_not_owning_aux1.rs6
-rw-r--r--tests/ui/directory_ownership/mod_file_not_owning_aux2.rs1
-rw-r--r--tests/ui/directory_ownership/mod_file_not_owning_aux3.rs3
-rw-r--r--tests/ui/lint/expansion-time-include.rs2
-rw-r--r--tests/ui/lint/known-tool-in-submodule/submodule.rs2
-rw-r--r--tests/ui/lint/lint_pre_expansion_extern_module_aux.rs2
-rw-r--r--tests/ui/lint/unknown-lints/other.rs4
-rw-r--r--tests/ui/lint/wasm_c_abi_transition.rs18
-rw-r--r--tests/ui/lint/wasm_c_abi_transition.stderr31
-rw-r--r--tests/ui/macros/auxiliary/macro-include-items-expr.rs2
-rw-r--r--tests/ui/macros/auxiliary/macro-include-items-item.rs2
-rw-r--r--tests/ui/macros/include-single-expr-helper-1.rs2
-rw-r--r--tests/ui/macros/include-single-expr-helper.rs2
-rw-r--r--tests/ui/macros/issue-69838-dir/bar.rs2
-rw-r--r--tests/ui/macros/issue-69838-dir/included.rs2
-rw-r--r--tests/ui/macros/macro-expanded-include/foo/mod.rs2
-rw-r--r--tests/ui/missing_non_modrs_mod/foo.rs3
-rw-r--r--tests/ui/missing_non_modrs_mod/foo_inline.rs2
-rw-r--r--tests/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr2
-rw-r--r--tests/ui/modules/mod_file_aux.rs3
-rw-r--r--tests/ui/modules_and_files_visibility/mod_file_aux.rs2
-rw-r--r--tests/ui/modules_and_files_visibility/mod_file_disambig_aux.rs2
-rw-r--r--tests/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs2
-rw-r--r--tests/ui/non_modrs_mods/foors_mod.rs4
-rw-r--r--tests/ui/non_modrs_mods_and_inline_mods/x.rs2
-rw-r--r--tests/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs2
-rw-r--r--tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs2
-rw-r--r--tests/ui/parser/circular_modules_hello.rs2
-rw-r--r--tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs2
-rw-r--r--tests/ui/parser/issues/issue-48508-aux.rs3
-rw-r--r--tests/ui/proc-macro/module.rs2
-rw-r--r--tests/ui/proc-macro/module_with_attrs.rs2
-rw-r--r--tests/ui/proc-macro/outer/inner.rs2
-rw-r--r--tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs2
-rw-r--r--tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs2
-rw-r--r--tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs2
-rw-r--r--tests/ui/runtime/backtrace-debuginfo-aux.rs3
-rw-r--r--tests/ui/traits/next-solver/supertrait-alias-1.rs22
-rw-r--r--tests/ui/traits/next-solver/supertrait-alias-2.rs25
-rw-r--r--tests/ui/traits/next-solver/supertrait-alias-3.rs32
-rw-r--r--tests/ui/traits/next-solver/supertrait-alias-4.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/tait-normalize.rs2
130 files changed, 1117 insertions, 476 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3d0e2942179..97a90a44a39 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2022,9 +2022,9 @@ checksum = "9fa0e2a1fcbe2f6be6c42e342259976206b383122fc152e872795338b5a3f3a7"
 
 [[package]]
 name = "libc"
-version = "0.2.171"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "libdbus-sys"
@@ -2573,16 +2573,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
 
 [[package]]
-name = "os_pipe"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982"
-dependencies = [
- "libc",
- "windows-sys 0.59.0",
-]
-
-[[package]]
 name = "overload"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3142,7 +3132,6 @@ dependencies = [
  "gimli 0.31.1",
  "libc",
  "object 0.36.7",
- "os_pipe",
  "regex",
  "serde_json",
  "similar",
@@ -3199,14 +3188,12 @@ dependencies = [
 
 [[package]]
 name = "rustc-rayon-core"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67668daaf00e359c126f6dcb40d652d89b458a008c8afa727a42a2d20fca0b7f"
+checksum = "2f42932dcd3bcbe484b38a3ccf79b7906fac41c02d408b5b1bac26da3416efdb"
 dependencies = [
- "crossbeam-channel",
  "crossbeam-deque",
  "crossbeam-utils",
- "num_cpus",
 ]
 
 [[package]]
diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
index 13a7c5a1805..2f918faaf75 100644
--- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs
+++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs
@@ -50,8 +50,16 @@ pub enum DiffActivity {
     /// with it.
     Dual,
     /// Forward Mode, Compute derivatives for this input/output and *overwrite* the shadow argument
+    /// with it. It expects the shadow argument to be `width` times larger than the original
+    /// input/output.
+    Dualv,
+    /// Forward Mode, Compute derivatives for this input/output and *overwrite* the shadow argument
     /// with it. Drop the code which updates the original input/output for maximum performance.
     DualOnly,
+    /// Forward Mode, Compute derivatives for this input/output and *overwrite* the shadow argument
+    /// with it. Drop the code which updates the original input/output for maximum performance.
+    /// It expects the shadow argument to be `width` times larger than the original input/output.
+    DualvOnly,
     /// Reverse Mode, Compute derivatives for this &T or *T input and *add* it to the shadow argument.
     Duplicated,
     /// Reverse Mode, Compute derivatives for this &T or *T input and *add* it to the shadow argument.
@@ -59,7 +67,15 @@ pub enum DiffActivity {
     DuplicatedOnly,
     /// All Integers must be Const, but these are used to mark the integer which represents the
     /// length of a slice/vec. This is used for safety checks on slices.
-    FakeActivitySize,
+    /// The integer (if given) specifies the size of the slice element in bytes.
+    FakeActivitySize(Option<u32>),
+}
+
+impl DiffActivity {
+    pub fn is_dual_or_const(&self) -> bool {
+        use DiffActivity::*;
+        matches!(self, |Dual| DualOnly | Dualv | DualvOnly | Const)
+    }
 }
 /// We generate one of these structs for each `#[autodiff(...)]` attribute.
 #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
@@ -131,11 +147,7 @@ pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool {
     match mode {
         DiffMode::Error => false,
         DiffMode::Source => false,
-        DiffMode::Forward => {
-            activity == DiffActivity::Dual
-                || activity == DiffActivity::DualOnly
-                || activity == DiffActivity::Const
-        }
+        DiffMode::Forward => activity.is_dual_or_const(),
         DiffMode::Reverse => {
             activity == DiffActivity::Const
                 || activity == DiffActivity::Active
@@ -153,10 +165,8 @@ pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool {
 pub fn valid_ty_for_activity(ty: &P<Ty>, activity: DiffActivity) -> bool {
     use DiffActivity::*;
     // It's always allowed to mark something as Const, since we won't compute derivatives wrt. it.
-    if matches!(activity, Const) {
-        return true;
-    }
-    if matches!(activity, Dual | DualOnly) {
+    // Dual variants also support all types.
+    if activity.is_dual_or_const() {
         return true;
     }
     // FIXME(ZuseZ4) We should make this more robust to also
@@ -172,9 +182,7 @@ pub fn valid_input_activity(mode: DiffMode, activity: DiffActivity) -> bool {
     return match mode {
         DiffMode::Error => false,
         DiffMode::Source => false,
-        DiffMode::Forward => {
-            matches!(activity, Dual | DualOnly | Const)
-        }
+        DiffMode::Forward => activity.is_dual_or_const(),
         DiffMode::Reverse => {
             matches!(activity, Active | ActiveOnly | Duplicated | DuplicatedOnly | Const)
         }
@@ -189,10 +197,12 @@ impl Display for DiffActivity {
             DiffActivity::Active => write!(f, "Active"),
             DiffActivity::ActiveOnly => write!(f, "ActiveOnly"),
             DiffActivity::Dual => write!(f, "Dual"),
+            DiffActivity::Dualv => write!(f, "Dualv"),
             DiffActivity::DualOnly => write!(f, "DualOnly"),
+            DiffActivity::DualvOnly => write!(f, "DualvOnly"),
             DiffActivity::Duplicated => write!(f, "Duplicated"),
             DiffActivity::DuplicatedOnly => write!(f, "DuplicatedOnly"),
-            DiffActivity::FakeActivitySize => write!(f, "FakeActivitySize"),
+            DiffActivity::FakeActivitySize(s) => write!(f, "FakeActivitySize({:?})", s),
         }
     }
 }
@@ -220,7 +230,9 @@ impl FromStr for DiffActivity {
             "ActiveOnly" => Ok(DiffActivity::ActiveOnly),
             "Const" => Ok(DiffActivity::Const),
             "Dual" => Ok(DiffActivity::Dual),
+            "Dualv" => Ok(DiffActivity::Dualv),
             "DualOnly" => Ok(DiffActivity::DualOnly),
+            "DualvOnly" => Ok(DiffActivity::DualvOnly),
             "Duplicated" => Ok(DiffActivity::Duplicated),
             "DuplicatedOnly" => Ok(DiffActivity::DuplicatedOnly),
             _ => Err(()),
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 4161829480d..daebd516499 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -799,8 +799,19 @@ mod llvm_enzyme {
                         d_inputs.push(shadow_arg.clone());
                     }
                 }
-                DiffActivity::Dual | DiffActivity::DualOnly => {
-                    for i in 0..x.width {
+                DiffActivity::Dual
+                | DiffActivity::DualOnly
+                | DiffActivity::Dualv
+                | DiffActivity::DualvOnly => {
+                    // the *v variants get lowered to enzyme_dupv and enzyme_dupnoneedv, which cause
+                    // Enzyme to not expect N arguments, but one argument (which is instead larger).
+                    let iterations =
+                        if matches!(activity, DiffActivity::Dualv | DiffActivity::DualvOnly) {
+                            1
+                        } else {
+                            x.width
+                        };
+                    for i in 0..iterations {
                         let mut shadow_arg = arg.clone();
                         let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind {
                             ident.name
@@ -823,7 +834,7 @@ mod llvm_enzyme {
                 DiffActivity::Const => {
                     // Nothing to do here.
                 }
-                DiffActivity::None | DiffActivity::FakeActivitySize => {
+                DiffActivity::None | DiffActivity::FakeActivitySize(_) => {
                     panic!("Should not happen");
                 }
             }
@@ -887,8 +898,8 @@ mod llvm_enzyme {
                 }
             };
 
-            if let DiffActivity::Dual = x.ret_activity {
-                let kind = if x.width == 1 {
+            if matches!(x.ret_activity, DiffActivity::Dual | DiffActivity::Dualv) {
+                let kind = if x.width == 1 || matches!(x.ret_activity, DiffActivity::Dualv) {
                     // Dual can only be used for f32/f64 ret.
                     // In that case we return now a tuple with two floats.
                     TyKind::Tup(thin_vec![ty.clone(), ty.clone()])
@@ -903,7 +914,7 @@ mod llvm_enzyme {
                 let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None });
                 d_decl.output = FnRetTy::Ty(ty);
             }
-            if let DiffActivity::DualOnly = x.ret_activity {
+            if matches!(x.ret_activity, DiffActivity::DualOnly | DiffActivity::DualvOnly) {
                 // No need to change the return type,
                 // we will just return the shadow in place of the primal return.
                 // However, if we have a width > 1, then we don't return -> T, but -> [T; width]
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 35134e9f5a0..27f7f95f100 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -123,7 +123,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
 /// Empty string, to be used where LLVM expects an instruction name, indicating
 /// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
 // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
-const UNNAMED: *const c_char = c"".as_ptr();
+pub(crate) const UNNAMED: *const c_char = c"".as_ptr();
 
 impl<'ll, CX: Borrow<SCx<'ll>>> BackendTypes for GenericBuilder<'_, 'll, CX> {
     type Value = <GenericCx<'ll, CX> as BackendTypes>::Value;
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index 5e7ef27143b..e7c071d05aa 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -10,7 +10,7 @@ use rustc_middle::bug;
 use tracing::{debug, trace};
 
 use crate::back::write::llvm_err;
-use crate::builder::SBuilder;
+use crate::builder::{SBuilder, UNNAMED};
 use crate::context::SimpleCx;
 use crate::declare::declare_simple_fn;
 use crate::errors::{AutoDiffWithoutEnable, LlvmError};
@@ -51,6 +51,7 @@ fn has_sret(fnc: &Value) -> bool {
 // using iterators and peek()?
 fn match_args_from_caller_to_enzyme<'ll>(
     cx: &SimpleCx<'ll>,
+    builder: &SBuilder<'ll, 'll>,
     width: u32,
     args: &mut Vec<&'ll llvm::Value>,
     inputs: &[DiffActivity],
@@ -78,7 +79,9 @@ fn match_args_from_caller_to_enzyme<'ll>(
     let enzyme_const = cx.create_metadata("enzyme_const".to_string()).unwrap();
     let enzyme_out = cx.create_metadata("enzyme_out".to_string()).unwrap();
     let enzyme_dup = cx.create_metadata("enzyme_dup".to_string()).unwrap();
+    let enzyme_dupv = cx.create_metadata("enzyme_dupv".to_string()).unwrap();
     let enzyme_dupnoneed = cx.create_metadata("enzyme_dupnoneed".to_string()).unwrap();
+    let enzyme_dupnoneedv = cx.create_metadata("enzyme_dupnoneedv".to_string()).unwrap();
 
     while activity_pos < inputs.len() {
         let diff_activity = inputs[activity_pos as usize];
@@ -90,13 +93,34 @@ fn match_args_from_caller_to_enzyme<'ll>(
             DiffActivity::Active => (enzyme_out, false),
             DiffActivity::ActiveOnly => (enzyme_out, false),
             DiffActivity::Dual => (enzyme_dup, true),
+            DiffActivity::Dualv => (enzyme_dupv, true),
             DiffActivity::DualOnly => (enzyme_dupnoneed, true),
+            DiffActivity::DualvOnly => (enzyme_dupnoneedv, true),
             DiffActivity::Duplicated => (enzyme_dup, true),
             DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true),
-            DiffActivity::FakeActivitySize => (enzyme_const, false),
+            DiffActivity::FakeActivitySize(_) => (enzyme_const, false),
         };
         let outer_arg = outer_args[outer_pos];
         args.push(cx.get_metadata_value(activity));
+        if matches!(diff_activity, DiffActivity::Dualv) {
+            let next_outer_arg = outer_args[outer_pos + 1];
+            let elem_bytes_size: u64 = match inputs[activity_pos + 1] {
+                DiffActivity::FakeActivitySize(Some(s)) => s.into(),
+                _ => bug!("incorrect Dualv handling recognized."),
+            };
+            // stride: sizeof(T) * n_elems.
+            // n_elems is the next integer.
+            // Now we multiply `4 * next_outer_arg` to get the stride.
+            let mul = unsafe {
+                llvm::LLVMBuildMul(
+                    builder.llbuilder,
+                    cx.get_const_i64(elem_bytes_size),
+                    next_outer_arg,
+                    UNNAMED,
+                )
+            };
+            args.push(mul);
+        }
         args.push(outer_arg);
         if duplicated {
             // We know that duplicated args by construction have a following argument,
@@ -114,7 +138,7 @@ fn match_args_from_caller_to_enzyme<'ll>(
                 } else {
                     let next_activity = inputs[activity_pos + 1];
                     // We analyze the MIR types and add this dummy activity if we visit a slice.
-                    next_activity == DiffActivity::FakeActivitySize
+                    matches!(next_activity, DiffActivity::FakeActivitySize(_))
                 }
             };
             if slice {
@@ -125,7 +149,10 @@ fn match_args_from_caller_to_enzyme<'ll>(
                 // int2 >= int1, which means the shadow vector is large enough to store the gradient.
                 assert_eq!(cx.type_kind(next_outer_ty), TypeKind::Integer);
 
-                for i in 0..(width as usize) {
+                let iterations =
+                    if matches!(diff_activity, DiffActivity::Dualv) { 1 } else { width as usize };
+
+                for i in 0..iterations {
                     let next_outer_arg2 = outer_args[outer_pos + 2 * (i + 1)];
                     let next_outer_ty2 = cx.val_ty(next_outer_arg2);
                     assert_eq!(cx.type_kind(next_outer_ty2), TypeKind::Pointer);
@@ -136,7 +163,7 @@ fn match_args_from_caller_to_enzyme<'ll>(
                 }
                 args.push(cx.get_metadata_value(enzyme_const));
                 args.push(next_outer_arg);
-                outer_pos += 2 + 2 * width as usize;
+                outer_pos += 2 + 2 * iterations;
                 activity_pos += 2;
             } else {
                 // A duplicated pointer will have the following two outer_fn arguments:
@@ -360,6 +387,7 @@ fn generate_enzyme_call<'ll>(
         let outer_args: Vec<&llvm::Value> = get_params(outer_fn);
         match_args_from_caller_to_enzyme(
             &cx,
+            &builder,
             attrs.width,
             &mut args,
             &attrs.input_activity,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
index ae2ab32ef53..56fb12d3c22 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs
@@ -247,6 +247,16 @@ pub(super) fn stub<'ll, 'tcx>(
     StubInfo { metadata, unique_type_id }
 }
 
+struct AdtStackPopGuard<'ll, 'tcx, 'a> {
+    cx: &'a CodegenCx<'ll, 'tcx>,
+}
+
+impl<'ll, 'tcx, 'a> Drop for AdtStackPopGuard<'ll, 'tcx, 'a> {
+    fn drop(&mut self) {
+        debug_context(self.cx).adt_stack.borrow_mut().pop();
+    }
+}
+
 /// This function enables creating debuginfo nodes that can recursively refer to themselves.
 /// It will first insert the given stub into the type map and only then execute the `members`
 /// and `generics` closures passed in. These closures have access to the stub so they can
@@ -261,6 +271,44 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
 ) -> DINodeCreationResult<'ll> {
     assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None);
 
+    let mut _adt_stack_pop_guard = None;
+    if let UniqueTypeId::Ty(ty, ..) = stub_info.unique_type_id
+        && let ty::Adt(adt_def, args) = ty.kind()
+    {
+        let def_id = adt_def.did();
+        // If any sub type reference the original type definition and the sub type has a type
+        // parameter that strictly contains the original parameter, the original type is a recursive
+        // type that can expanding indefinitely. Example,
+        // ```
+        // enum Recursive<T> {
+        //     Recurse(*const Recursive<Wrap<T>>),
+        //     Item(T),
+        // }
+        // ```
+        let is_expanding_recursive =
+            debug_context(cx).adt_stack.borrow().iter().any(|(parent_def_id, parent_args)| {
+                if def_id == *parent_def_id {
+                    args.iter().zip(parent_args.iter()).any(|(arg, parent_arg)| {
+                        if let (Some(arg), Some(parent_arg)) = (arg.as_type(), parent_arg.as_type())
+                        {
+                            arg != parent_arg && arg.contains(parent_arg)
+                        } else {
+                            false
+                        }
+                    })
+                } else {
+                    false
+                }
+            });
+        if is_expanding_recursive {
+            // FIXME: indicate that this is an expanding recursive type in stub metadata?
+            return DINodeCreationResult::new(stub_info.metadata, false);
+        } else {
+            debug_context(cx).adt_stack.borrow_mut().push((def_id, args));
+            _adt_stack_pop_guard = Some(AdtStackPopGuard { cx });
+        }
+    }
+
     debug_context(cx).type_map.insert(stub_info.unique_type_id, stub_info.metadata);
 
     let members: SmallVec<_> =
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 0f94a1dbb0d..c5085927923 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -66,6 +66,7 @@ pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
     created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
 
     type_map: metadata::TypeMap<'ll, 'tcx>,
+    adt_stack: RefCell<Vec<(DefId, GenericArgsRef<'tcx>)>>,
     namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
     recursion_marker_type: OnceCell<&'ll DIType>,
 }
@@ -80,6 +81,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
             builder,
             created_files: Default::default(),
             type_map: Default::default(),
+            adt_stack: Default::default(),
             namespace_map: RefCell::new(Default::default()),
             recursion_marker_type: OnceCell::new(),
         }
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 2b74c849f1a..b600b8918dd 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -34,7 +34,7 @@ use crate::check_consts::is_fn_or_trait_safe_to_expose_on_stable;
 use crate::errors;
 
 type QualifResults<'mir, 'tcx, Q> =
-    rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>;
+    rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'tcx, Q>>;
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum ConstConditionsHold {
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 8cee282311f..9f7fcc509a5 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -22,17 +22,17 @@ use super::{ConstCx, Qualif, qualifs};
 /// qualified immediately after it is borrowed or its address escapes. The borrow must allow for
 /// mutation, which includes shared borrows of places with interior mutability. The type of
 /// borrowed place must contain the qualif.
-struct TransferFunction<'a, 'mir, 'tcx, Q> {
-    ccx: &'a ConstCx<'mir, 'tcx>,
-    state: &'a mut State,
+struct TransferFunction<'mir, 'tcx, Q> {
+    ccx: &'mir ConstCx<'mir, 'tcx>,
+    state: &'mir mut State,
     _qualif: PhantomData<Q>,
 }
 
-impl<'a, 'mir, 'tcx, Q> TransferFunction<'a, 'mir, 'tcx, Q>
+impl<'mir, 'tcx, Q> TransferFunction<'mir, 'tcx, Q>
 where
     Q: Qualif,
 {
-    fn new(ccx: &'a ConstCx<'mir, 'tcx>, state: &'a mut State) -> Self {
+    fn new(ccx: &'mir ConstCx<'mir, 'tcx>, state: &'mir mut State) -> Self {
         TransferFunction { ccx, state, _qualif: PhantomData }
     }
 
@@ -124,7 +124,7 @@ where
     }
 }
 
-impl<'tcx, Q> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx, Q>
+impl<'tcx, Q> Visitor<'tcx> for TransferFunction<'_, 'tcx, Q>
 where
     Q: Qualif,
 {
@@ -228,20 +228,20 @@ where
 }
 
 /// The dataflow analysis used to propagate qualifs on arbitrary CFGs.
-pub(super) struct FlowSensitiveAnalysis<'a, 'mir, 'tcx, Q> {
-    ccx: &'a ConstCx<'mir, 'tcx>,
+pub(super) struct FlowSensitiveAnalysis<'mir, 'tcx, Q> {
+    ccx: &'mir ConstCx<'mir, 'tcx>,
     _qualif: PhantomData<Q>,
 }
 
-impl<'a, 'mir, 'tcx, Q> FlowSensitiveAnalysis<'a, 'mir, 'tcx, Q>
+impl<'mir, 'tcx, Q> FlowSensitiveAnalysis<'mir, 'tcx, Q>
 where
     Q: Qualif,
 {
-    pub(super) fn new(_: Q, ccx: &'a ConstCx<'mir, 'tcx>) -> Self {
+    pub(super) fn new(_: Q, ccx: &'mir ConstCx<'mir, 'tcx>) -> Self {
         FlowSensitiveAnalysis { ccx, _qualif: PhantomData }
     }
 
-    fn transfer_function(&self, state: &'a mut State) -> TransferFunction<'a, 'mir, 'tcx, Q> {
+    fn transfer_function(&self, state: &'mir mut State) -> TransferFunction<'mir, 'tcx, Q> {
         TransferFunction::<Q>::new(self.ccx, state)
     }
 }
@@ -313,7 +313,7 @@ impl JoinSemiLattice for State {
     }
 }
 
-impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q>
+impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, 'tcx, Q>
 where
     Q: Qualif,
 {
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index c1948e9f31f..b69bc0918be 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Call this on things you got out of the MIR (so it is as generic as the current
     /// stack frame), to bring it into the proper environment for this interpreter.
-    pub(super) fn instantiate_from_current_frame_and_normalize_erasing_regions<
+    pub fn instantiate_from_current_frame_and_normalize_erasing_regions<
         T: TypeFoldable<TyCtxt<'tcx>>,
     >(
         &self,
@@ -279,9 +279,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Call this on things you got out of the MIR (so it is as generic as the provided
     /// stack frame), to bring it into the proper environment for this interpreter.
-    pub(super) fn instantiate_from_frame_and_normalize_erasing_regions<
-        T: TypeFoldable<TyCtxt<'tcx>>,
-    >(
+    pub fn instantiate_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
         &self,
         frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
         value: T,
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index e4b2fe5d153..8f0cb197c44 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -30,6 +30,7 @@ use super::{
     AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy, err_ub, interp_ok,
 };
 use crate::const_eval;
+use crate::const_eval::DummyMachine;
 use crate::errors::NestedStaticInThreadLocal;
 
 pub trait CompileTimeMachine<'tcx, T> = Machine<
@@ -323,14 +324,17 @@ pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>>
     interp_ok(())
 }
 
-impl<'tcx, M: super::intern::CompileTimeMachine<'tcx, !>> InterpCx<'tcx, M> {
+impl<'tcx> InterpCx<'tcx, DummyMachine> {
     /// A helper function that allocates memory for the layout given and gives you access to mutate
     /// it. Once your own mutation code is done, the backing `Allocation` is removed from the
     /// current `Memory` and interned as read-only into the global memory.
     pub fn intern_with_temp_alloc(
         &mut self,
         layout: TyAndLayout<'tcx>,
-        f: impl FnOnce(&mut InterpCx<'tcx, M>, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, ()>,
+        f: impl FnOnce(
+            &mut InterpCx<'tcx, DummyMachine>,
+            &PlaceTy<'tcx, CtfeProvenance>,
+        ) -> InterpResult<'tcx, ()>,
     ) -> InterpResult<'tcx, AllocId> {
         // `allocate` picks a fresh AllocId that we will associate with its data below.
         let dest = self.allocate(layout, MemoryKind::Stack)?;
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 27df8f0e98a..0511f4e25ad 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -1502,16 +1502,21 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         let mut projections = base_place.place.projections;
 
         let node_ty = self.cx.typeck_results().node_type(node);
-        // Opaque types can't have field projections, but we can instead convert
-        // the current place in-place (heh) to the hidden type, and then apply all
-        // follow up projections on that.
-        if node_ty != place_ty
-            && self
-                .cx
-                .try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
-                .is_impl_trait()
-        {
-            projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
+        if !self.cx.tcx().next_trait_solver_globally() {
+            // Opaque types can't have field projections, but we can instead convert
+            // the current place in-place (heh) to the hidden type, and then apply all
+            // follow up projections on that.
+            if node_ty != place_ty
+                && self
+                    .cx
+                    .try_structurally_resolve_type(
+                        self.cx.tcx().hir_span(base_place.hir_id),
+                        place_ty,
+                    )
+                    .is_impl_trait()
+            {
+                projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
+            }
         }
         projections.push(Projection { kind, ty });
         PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs
index 67ac805c2bf..d2702bdb057 100644
--- a/compiler/rustc_index/src/slice.rs
+++ b/compiler/rustc_index/src/slice.rs
@@ -1,6 +1,6 @@
 use std::fmt;
 use std::marker::PhantomData;
-use std::ops::{Index, IndexMut};
+use std::ops::{Index, IndexMut, RangeBounds};
 use std::slice::GetDisjointMutError::*;
 use std::slice::{self, SliceIndex};
 
@@ -105,6 +105,17 @@ impl<I: Idx, T> IndexSlice<I, T> {
     }
 
     #[inline]
+    pub fn copy_within(
+        &mut self,
+        src: impl IntoSliceIdx<I, [T], Output: RangeBounds<usize>>,
+        dest: I,
+    ) where
+        T: Copy,
+    {
+        self.raw.copy_within(src.into_slice_idx(), dest.index());
+    }
+
+    #[inline]
     pub fn get<R: IntoSliceIdx<I, [T]>>(
         &self,
         index: R,
diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs
index 60ce8544aa0..c3d10615cf1 100644
--- a/compiler/rustc_middle/src/hir/place.rs
+++ b/compiler/rustc_middle/src/hir/place.rs
@@ -40,6 +40,8 @@ pub enum ProjectionKind {
 
     /// A conversion from an opaque type to its hidden type so we can
     /// do further projections on it.
+    ///
+    /// This is unused if `-Znext-solver` is enabled.
     OpaqueCast,
 }
 
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index c7561f8afef..304b3caa6e1 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1242,6 +1242,8 @@ pub enum ProjectionElem<V, T> {
 
     /// Like an explicit cast from an opaque type to a concrete type, but without
     /// requiring an intermediate variable.
+    ///
+    /// This is unused with `-Znext-solver`.
     OpaqueCast(T),
 
     /// A transmute from an unsafe binder to the type that it wraps. This is a projection
diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
index 9670c1716f5..d66b38c5b00 100644
--- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
@@ -101,18 +101,21 @@ impl<'tcx> MatchPairTree<'tcx> {
             place_builder = resolved;
         }
 
-        // Only add the OpaqueCast projection if the given place is an opaque type and the
-        // expected type from the pattern is not.
-        let may_need_cast = match place_builder.base() {
-            PlaceBase::Local(local) => {
-                let ty =
-                    Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx).ty;
-                ty != pattern.ty && ty.has_opaque_types()
+        if !cx.tcx.next_trait_solver_globally() {
+            // Only add the OpaqueCast projection if the given place is an opaque type and the
+            // expected type from the pattern is not.
+            let may_need_cast = match place_builder.base() {
+                PlaceBase::Local(local) => {
+                    let ty =
+                        Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx)
+                            .ty;
+                    ty != pattern.ty && ty.has_opaque_types()
+                }
+                _ => true,
+            };
+            if may_need_cast {
+                place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
             }
-            _ => true,
-        };
-        if may_need_cast {
-            place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
         }
 
         let place = place_builder.try_to_place(cx);
diff --git a/compiler/rustc_mir_transform/src/post_analysis_normalize.rs b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs
index 76c2f082c0b..5599dee4cca 100644
--- a/compiler/rustc_mir_transform/src/post_analysis_normalize.rs
+++ b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs
@@ -39,20 +39,22 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> {
         _context: PlaceContext,
         _location: Location,
     ) {
-        // Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
-        if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
-            return;
+        if !self.tcx.next_trait_solver_globally() {
+            // `OpaqueCast` projections are only needed if there are opaque types on which projections
+            // are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
+            // hidden types, so we don't need these projections anymore.
+            //
+            // Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
+            if place.projection.iter().any(|elem| matches!(elem, ProjectionElem::OpaqueCast(_))) {
+                place.projection = self.tcx.mk_place_elems(
+                    &place
+                        .projection
+                        .into_iter()
+                        .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
+                        .collect::<Vec<_>>(),
+                );
+            };
         }
-        // `OpaqueCast` projections are only needed if there are opaque types on which projections
-        // are performed. After the `PostAnalysisNormalize` pass, all opaque types are replaced with their
-        // hidden types, so we don't need these projections anymore.
-        place.projection = self.tcx.mk_place_elems(
-            &place
-                .projection
-                .into_iter()
-                .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
-                .collect::<Vec<_>>(),
-        );
         self.super_place(place, _context, _location);
     }
 
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index 0f5bdc8d768..81bf8c5d21c 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -99,6 +99,12 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool
         return true;
     }
 
+    // Both the old and the new ABIs treat vector types like `v128` the same
+    // way.
+    if uses_vector_registers(&arg.mode, &arg.layout.backend_repr) {
+        return true;
+    }
+
     // This matches `unwrap_trivial_aggregate` in the wasm ABI logic.
     if arg.layout.is_aggregate() {
         let cx = LayoutCx::new(tcx, TypingEnv::fully_monomorphized());
@@ -111,6 +117,11 @@ fn wasm_abi_safe<'tcx>(tcx: TyCtxt<'tcx>, arg: &ArgAbi<'tcx, Ty<'tcx>>) -> bool
         }
     }
 
+    // Zero-sized types are dropped in both ABIs, so they're safe
+    if arg.layout.is_zst() {
+        return true;
+    }
+
     false
 }
 
diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs
index ebe0b258c1b..22d593b80b8 100644
--- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs
@@ -2,7 +2,7 @@ use rustc_ast::expand::autodiff_attrs::{AutoDiffItem, DiffActivity};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_middle::bug;
 use rustc_middle::mir::mono::MonoItem;
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::ty::{self, Instance, PseudoCanonicalInput, Ty, TyCtxt, TypingEnv};
 use rustc_symbol_mangling::symbol_name_for_instance_in_crate;
 use tracing::{debug, trace};
 
@@ -22,23 +22,51 @@ fn adjust_activity_to_abi<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>, da: &mut Vec
     for (i, ty) in sig.inputs().iter().enumerate() {
         if let Some(inner_ty) = ty.builtin_deref(true) {
             if inner_ty.is_slice() {
+                // Now we need to figure out the size of each slice element in memory to allow
+                // safety checks and usability improvements in the backend.
+                let sty = match inner_ty.builtin_index() {
+                    Some(sty) => sty,
+                    None => {
+                        panic!("slice element type unknown");
+                    }
+                };
+                let pci = PseudoCanonicalInput {
+                    typing_env: TypingEnv::fully_monomorphized(),
+                    value: sty,
+                };
+
+                let layout = tcx.layout_of(pci);
+                let elem_size = match layout {
+                    Ok(layout) => layout.size,
+                    Err(_) => {
+                        bug!("autodiff failed to compute slice element size");
+                    }
+                };
+                let elem_size: u32 = elem_size.bytes() as u32;
+
                 // We know that the length will be passed as extra arg.
                 if !da.is_empty() {
                     // We are looking at a slice. The length of that slice will become an
                     // extra integer on llvm level. Integers are always const.
                     // However, if the slice get's duplicated, we want to know to later check the
                     // size. So we mark the new size argument as FakeActivitySize.
+                    // There is one FakeActivitySize per slice, so for convenience we store the
+                    // slice element size in bytes in it. We will use the size in the backend.
                     let activity = match da[i] {
                         DiffActivity::DualOnly
                         | DiffActivity::Dual
+                        | DiffActivity::Dualv
                         | DiffActivity::DuplicatedOnly
-                        | DiffActivity::Duplicated => DiffActivity::FakeActivitySize,
+                        | DiffActivity::Duplicated => {
+                            DiffActivity::FakeActivitySize(Some(elem_size))
+                        }
                         DiffActivity::Const => DiffActivity::Const,
                         _ => bug!("unexpected activity for ptr/ref"),
                     };
                     new_activities.push(activity);
                     new_positions.push(i + 1);
                 }
+
                 continue;
             }
         }
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index ee000b11748..83b2465d05a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -92,16 +92,20 @@ where
             let ty::Dynamic(bounds, _, _) = goal.predicate.self_ty().kind() else {
                 panic!("expected object type in `probe_and_consider_object_bound_candidate`");
             };
-            ecx.add_goals(
-                GoalSource::ImplWhereBound,
-                structural_traits::predicates_for_object_candidate(
-                    ecx,
-                    goal.param_env,
-                    goal.predicate.trait_ref(cx),
-                    bounds,
-                ),
-            );
-            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            match structural_traits::predicates_for_object_candidate(
+                ecx,
+                goal.param_env,
+                goal.predicate.trait_ref(cx),
+                bounds,
+            ) {
+                Ok(requirements) => {
+                    ecx.add_goals(GoalSource::ImplWhereBound, requirements);
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                }
+                Err(_) => {
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                }
+            }
         })
     }
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index c2fb592c3f3..1526049719e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -5,9 +5,10 @@ use derive_where::derive_where;
 use rustc_type_ir::data_structures::HashMap;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
+use rustc_type_ir::solve::inspect::ProbeKind;
 use rustc_type_ir::{
-    self as ty, Interner, Movability, Mutability, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    Upcast as _, elaborate,
+    self as ty, FallibleTypeFolder, Interner, Movability, Mutability, TypeFoldable,
+    TypeSuperFoldable, Upcast as _, elaborate,
 };
 use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
 use tracing::instrument;
@@ -822,22 +823,16 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
 /// impl Baz for dyn Foo<Item = Ty> {}
 /// ```
 ///
-/// However, in order to make such impls well-formed, we need to do an
+/// However, in order to make such impls non-cyclical, we need to do an
 /// additional step of eagerly folding the associated types in the where
 /// clauses of the impl. In this example, that means replacing
 /// `<Self as Foo>::Bar` with `Ty` in the first impl.
-///
-// FIXME: This is only necessary as `<Self as Trait>::Assoc: ItemBound`
-// bounds in impls are trivially proven using the item bound candidates.
-// This is unsound in general and once that is fixed, we don't need to
-// normalize eagerly here. See https://github.com/lcnr/solver-woes/issues/9
-// for more details.
 pub(in crate::solve) fn predicates_for_object_candidate<D, I>(
-    ecx: &EvalCtxt<'_, D>,
+    ecx: &mut EvalCtxt<'_, D>,
     param_env: I::ParamEnv,
     trait_ref: ty::TraitRef<I>,
     object_bounds: I::BoundExistentialPredicates,
-) -> Vec<Goal<I, I::Predicate>>
+) -> Result<Vec<Goal<I, I::Predicate>>, Ambiguous>
 where
     D: SolverDelegate<Interner = I>,
     I: Interner,
@@ -871,72 +866,130 @@ where
             .extend(cx.item_bounds(associated_type_def_id).iter_instantiated(cx, trait_ref.args));
     }
 
-    let mut replace_projection_with = HashMap::default();
+    let mut replace_projection_with: HashMap<_, Vec<_>> = HashMap::default();
     for bound in object_bounds.iter() {
         if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
+            // FIXME: We *probably* should replace this with a dummy placeholder,
+            // b/c don't want to replace literal instances of this dyn type that
+            // show up in the bounds, but just ones that come from substituting
+            // `Self` with the dyn type.
             let proj = proj.with_self_ty(cx, trait_ref.self_ty());
-            let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));
-            assert_eq!(
-                old_ty,
-                None,
-                "{:?} has two generic parameters: {:?} and {:?}",
-                proj.projection_term,
-                proj.term,
-                old_ty.unwrap()
-            );
+            replace_projection_with.entry(proj.def_id()).or_default().push(bound.rebind(proj));
         }
     }
 
-    let mut folder =
-        ReplaceProjectionWith { ecx, param_env, mapping: replace_projection_with, nested: vec![] };
-    let folded_requirements = requirements.fold_with(&mut folder);
+    let mut folder = ReplaceProjectionWith {
+        ecx,
+        param_env,
+        self_ty: trait_ref.self_ty(),
+        mapping: &replace_projection_with,
+        nested: vec![],
+    };
 
-    folder
+    let requirements = requirements.try_fold_with(&mut folder)?;
+    Ok(folder
         .nested
         .into_iter()
-        .chain(folded_requirements.into_iter().map(|clause| Goal::new(cx, param_env, clause)))
-        .collect()
+        .chain(requirements.into_iter().map(|clause| Goal::new(cx, param_env, clause)))
+        .collect())
 }
 
-struct ReplaceProjectionWith<'a, D: SolverDelegate<Interner = I>, I: Interner> {
-    ecx: &'a EvalCtxt<'a, D>,
+struct ReplaceProjectionWith<'a, 'b, I: Interner, D: SolverDelegate<Interner = I>> {
+    ecx: &'a mut EvalCtxt<'b, D>,
     param_env: I::ParamEnv,
-    mapping: HashMap<I::DefId, ty::Binder<I, ty::ProjectionPredicate<I>>>,
+    self_ty: I::Ty,
+    mapping: &'a HashMap<I::DefId, Vec<ty::Binder<I, ty::ProjectionPredicate<I>>>>,
     nested: Vec<Goal<I, I::Predicate>>,
 }
 
-impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I>
-    for ReplaceProjectionWith<'_, D, I>
+impl<D, I> ReplaceProjectionWith<'_, '_, I, D>
+where
+    D: SolverDelegate<Interner = I>,
+    I: Interner,
 {
+    fn projection_may_match(
+        &mut self,
+        source_projection: ty::Binder<I, ty::ProjectionPredicate<I>>,
+        target_projection: ty::AliasTerm<I>,
+    ) -> bool {
+        source_projection.item_def_id() == target_projection.def_id
+            && self
+                .ecx
+                .probe(|_| ProbeKind::ProjectionCompatibility)
+                .enter(|ecx| -> Result<_, NoSolution> {
+                    let source_projection = ecx.instantiate_binder_with_infer(source_projection);
+                    ecx.eq(self.param_env, source_projection.projection_term, target_projection)?;
+                    ecx.try_evaluate_added_goals()
+                })
+                .is_ok()
+    }
+
+    /// Try to replace an alias with the term present in the projection bounds of the self type.
+    /// Returns `Ok<None>` if this alias is not eligible to be replaced, or bail with
+    /// `Err(Ambiguous)` if it's uncertain which projection bound to replace the term with due
+    /// to multiple bounds applying.
+    fn try_eagerly_replace_alias(
+        &mut self,
+        alias_term: ty::AliasTerm<I>,
+    ) -> Result<Option<I::Term>, Ambiguous> {
+        if alias_term.self_ty() != self.self_ty {
+            return Ok(None);
+        }
+
+        let Some(replacements) = self.mapping.get(&alias_term.def_id) else {
+            return Ok(None);
+        };
+
+        // This is quite similar to the `projection_may_match` we use in unsizing,
+        // but here we want to unify a projection predicate against an alias term
+        // so we can replace it with the the projection predicate's term.
+        let mut matching_projections = replacements
+            .iter()
+            .filter(|source_projection| self.projection_may_match(**source_projection, alias_term));
+        let Some(replacement) = matching_projections.next() else {
+            // This shouldn't happen.
+            panic!("could not replace {alias_term:?} with term from from {:?}", self.self_ty);
+        };
+        // FIXME: This *may* have issues with duplicated projections.
+        if matching_projections.next().is_some() {
+            // If there's more than one projection that we can unify here, then we
+            // need to stall until inference constrains things so that there's only
+            // one choice.
+            return Err(Ambiguous);
+        }
+
+        let replacement = self.ecx.instantiate_binder_with_infer(*replacement);
+        self.nested.extend(
+            self.ecx
+                .eq_and_get_goals(self.param_env, alias_term, replacement.projection_term)
+                .expect("expected to be able to unify goal projection with dyn's projection"),
+        );
+
+        Ok(Some(replacement.term))
+    }
+}
+
+/// Marker for bailing with ambiguity.
+pub(crate) struct Ambiguous;
+
+impl<D, I> FallibleTypeFolder<I> for ReplaceProjectionWith<'_, '_, I, D>
+where
+    D: SolverDelegate<Interner = I>,
+    I: Interner,
+{
+    type Error = Ambiguous;
+
     fn cx(&self) -> I {
         self.ecx.cx()
     }
 
-    fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
+    fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> {
         if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
-            if let Some(replacement) = self.mapping.get(&alias_ty.def_id) {
-                // We may have a case where our object type's projection bound is higher-ranked,
-                // but the where clauses we instantiated are not. We can solve this by instantiating
-                // the binder at the usage site.
-                let proj = self.ecx.instantiate_binder_with_infer(*replacement);
-                // FIXME: Technically this equate could be fallible...
-                self.nested.extend(
-                    self.ecx
-                        .eq_and_get_goals(
-                            self.param_env,
-                            alias_ty,
-                            proj.projection_term.expect_ty(self.ecx.cx()),
-                        )
-                        .expect(
-                            "expected to be able to unify goal projection with dyn's projection",
-                        ),
-                );
-                proj.term.expect_ty()
-            } else {
-                ty.super_fold_with(self)
+            if let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? {
+                return Ok(term.expect_ty());
             }
-        } else {
-            ty.super_fold_with(self)
         }
+
+        ty.try_super_fold_with(self)
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 9262da2906d..409af8568d7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -944,7 +944,7 @@ where
              target_projection: ty::Binder<I, ty::ExistentialProjection<I>>| {
                 source_projection.item_def_id() == target_projection.item_def_id()
                     && ecx
-                        .probe(|_| ProbeKind::UpcastProjectionCompatibility)
+                        .probe(|_| ProbeKind::ProjectionCompatibility)
                         .enter(|ecx| -> Result<_, NoSolution> {
                             ecx.enter_forall(target_projection, |ecx, target_projection| {
                                 let source_projection =
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 202378560ee..ff7ea5bd718 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2065,7 +2065,8 @@ fn collect_print_requests(
             check_print_request_stability(early_dcx, unstable_opts, (print_name, *print_kind));
             *print_kind
         } else {
-            emit_unknown_print_request_help(early_dcx, req)
+            let is_nightly = nightly_options::match_is_nightly_build(matches);
+            emit_unknown_print_request_help(early_dcx, req, is_nightly)
         };
 
         let out = out.unwrap_or(OutFileName::Stdout);
@@ -2089,25 +2090,37 @@ fn check_print_request_stability(
     unstable_opts: &UnstableOptions,
     (print_name, print_kind): (&str, PrintKind),
 ) {
+    if !is_print_request_stable(print_kind) && !unstable_opts.unstable_options {
+        early_dcx.early_fatal(format!(
+            "the `-Z unstable-options` flag must also be passed to enable the `{print_name}` \
+                print option"
+        ));
+    }
+}
+
+fn is_print_request_stable(print_kind: PrintKind) -> bool {
     match print_kind {
         PrintKind::AllTargetSpecsJson
         | PrintKind::CheckCfg
         | PrintKind::CrateRootLintLevels
         | PrintKind::SupportedCrateTypes
-        | PrintKind::TargetSpecJson
-            if !unstable_opts.unstable_options =>
-        {
-            early_dcx.early_fatal(format!(
-                "the `-Z unstable-options` flag must also be passed to enable the `{print_name}` \
-                print option"
-            ));
-        }
-        _ => {}
+        | PrintKind::TargetSpecJson => false,
+        _ => true,
     }
 }
 
-fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str) -> ! {
-    let prints = PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
+fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str, is_nightly: bool) -> ! {
+    let prints = PRINT_KINDS
+        .iter()
+        .filter_map(|(name, kind)| {
+            // If we're not on nightly, we don't want to print unstable options
+            if !is_nightly && !is_print_request_stable(*kind) {
+                None
+            } else {
+                Some(format!("`{name}`"))
+            }
+        })
+        .collect::<Vec<_>>();
     let prints = prints.join(", ");
 
     let mut diag = early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 48a05ad29fb..24b87000e32 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -292,7 +292,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                 inspect::ProbeStep::NestedProbe(ref probe) => {
                     match probe.kind {
                         // These never assemble candidates for the goal we're trying to solve.
-                        inspect::ProbeKind::UpcastProjectionCompatibility
+                        inspect::ProbeKind::ProjectionCompatibility
                         | inspect::ProbeKind::ShadowedEnvProbing => continue,
 
                         inspect::ProbeKind::NormalizedSelfTyAssembly
@@ -314,8 +314,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
         }
 
         match probe.kind {
-            inspect::ProbeKind::UpcastProjectionCompatibility
-            | inspect::ProbeKind::ShadowedEnvProbing => bug!(),
+            inspect::ProbeKind::ProjectionCompatibility
+            | inspect::ProbeKind::ShadowedEnvProbing => {
+                bug!()
+            }
 
             inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly => {}
 
diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs
index 4437fc5b029..4fdaf740287 100644
--- a/compiler/rustc_trait_selection/src/solve/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/select.rs
@@ -177,7 +177,7 @@ fn to_selection<'tcx>(
         },
         ProbeKind::NormalizedSelfTyAssembly
         | ProbeKind::UnsizeAssembly
-        | ProbeKind::UpcastProjectionCompatibility
+        | ProbeKind::ProjectionCompatibility
         | ProbeKind::OpaqueTypeStorageLookup { result: _ }
         | ProbeKind::Root { result: _ }
         | ProbeKind::ShadowedEnvProbing
diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs
index 18fb71dd290..b10641b287d 100644
--- a/compiler/rustc_type_ir/src/solve/inspect.rs
+++ b/compiler/rustc_type_ir/src/solve/inspect.rs
@@ -118,10 +118,12 @@ pub enum ProbeKind<I: Interner> {
     /// Used in the probe that wraps normalizing the non-self type for the unsize
     /// trait, which is also structurally matched on.
     UnsizeAssembly,
-    /// During upcasting from some source object to target object type, used to
-    /// do a probe to find out what projection type(s) may be used to prove that
-    /// the source type upholds all of the target type's object bounds.
-    UpcastProjectionCompatibility,
+    /// Used to do a probe to find out what projection type(s) match a given
+    /// alias bound or projection predicate. For trait upcasting, this is used
+    /// to prove that the source type upholds all of the target type's object
+    /// bounds. For object type bounds, this is used when eagerly replacing
+    /// supertrait aliases.
+    ProjectionCompatibility,
     /// Looking for param-env candidates that satisfy the trait ref for a projection.
     ShadowedEnvProbing,
     /// Try to unify an opaque type with an existing key in the storage.
diff --git a/diff b/diff
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/diff
+++ /dev/null
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 29e0e134da7..e4f1c4ec96a 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -67,9 +67,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.153"
+version = "0.1.155"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "926ef6a360c15a911023352fd6969c51605d70495406f735beb1ca0257448e59"
+checksum = "341e0830ca6170a4fcf02e92e57daf4b6f10142d48da32a547023867a6c8b35e"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index ee8cb9d25a3..cedbd330cbd 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -16,7 +16,7 @@ bench = false
 
 [dependencies]
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.153", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.155", features = ['rustc-dep-of-std'] }
 
 [features]
 compiler-builtins-mem = ['compiler_builtins/mem']
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index f6708cc4bc9..1ca23ab6eea 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -4,6 +4,7 @@
 //!
 //! Hints may be compile time or runtime.
 
+use crate::mem::MaybeUninit;
 use crate::{intrinsics, ub_checks};
 
 /// Informs the compiler that the site which is calling this function is not
@@ -735,9 +736,9 @@ pub const fn cold_path() {
     crate::intrinsics::cold_path()
 }
 
-/// Returns either `true_val` or `false_val` depending on the value of `b`,
-/// with a hint to the compiler that `b` is unlikely to be correctly
-/// predicted by a CPUโ€™s branch predictor.
+/// Returns either `true_val` or `false_val` depending on the value of
+/// `condition`, with a hint to the compiler that `condition` is unlikely to be
+/// correctly predicted by a CPUโ€™s branch predictor.
 ///
 /// This method is functionally equivalent to
 /// ```ignore (this is just for illustrative purposes)
@@ -753,10 +754,10 @@ pub const fn cold_path() {
 /// search.
 ///
 /// Note however that this lowering is not guaranteed (on any platform) and
-/// should not be relied upon when trying to write constant-time code. Also
-/// be aware that this lowering might *decrease* performance if `condition`
-/// is well-predictable. It is advisable to perform benchmarks to tell if
-/// this function is useful.
+/// should not be relied upon when trying to write cryptographic constant-time
+/// code. Also be aware that this lowering might *decrease* performance if
+/// `condition` is well-predictable. It is advisable to perform benchmarks to
+/// tell if this function is useful.
 ///
 /// # Examples
 ///
@@ -780,6 +781,17 @@ pub const fn cold_path() {
 /// ```
 #[inline(always)]
 #[unstable(feature = "select_unpredictable", issue = "133962")]
-pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
-    crate::intrinsics::select_unpredictable(b, true_val, false_val)
+pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T {
+    // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/245):
+    // Change this to use ManuallyDrop instead.
+    let mut true_val = MaybeUninit::new(true_val);
+    let mut false_val = MaybeUninit::new(false_val);
+    // SAFETY: The value that is not selected is dropped, and the selected one
+    // is returned. This is necessary because the intrinsic doesn't drop the
+    // value that is  not selected.
+    unsafe {
+        crate::intrinsics::select_unpredictable(!condition, &mut true_val, &mut false_val)
+            .assume_init_drop();
+        crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init()
+    }
 }
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index e5604d277f5..a01efb2adeb 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -1327,6 +1327,8 @@ pub const fn unlikely(b: bool) -> bool {
 /// any safety invariants.
 ///
 /// The public form of this instrinsic is [`core::hint::select_unpredictable`].
+/// However unlike the public form, the intrinsic will not drop the value that
+/// is not selected.
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
 #[rustc_nounwind]
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 08c34e852da..d3d1eebc227 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -224,14 +224,16 @@ impl f128 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE 754 doesn't define just a single NaN value;
-    /// a plethora of bit patterns are considered to be NaN.
-    /// Furthermore, the standard makes a difference
-    /// between a "signaling" and a "quiet" NaN,
-    /// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
-    /// This constant isn't guaranteed to equal to any specific NaN bitpattern,
-    /// and the stability of its representation over Rust versions
-    /// and target platforms isn't guaranteed.
+    /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
+    /// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
+    /// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
+    /// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
+    /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
+    /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
+    /// The concrete bit pattern may change across Rust versions and target platforms.
     #[allow(clippy::eq_op)]
     #[rustc_diagnostic_item = "f128_nan"]
     #[unstable(feature = "f128", issue = "116909")]
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index a33e5f53014..dceb30177e6 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -219,14 +219,16 @@ impl f16 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE 754 doesn't define just a single NaN value;
-    /// a plethora of bit patterns are considered to be NaN.
-    /// Furthermore, the standard makes a difference
-    /// between a "signaling" and a "quiet" NaN,
-    /// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
-    /// This constant isn't guaranteed to equal to any specific NaN bitpattern,
-    /// and the stability of its representation over Rust versions
-    /// and target platforms isn't guaranteed.
+    /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
+    /// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
+    /// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
+    /// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
+    /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
+    /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
+    /// The concrete bit pattern may change across Rust versions and target platforms.
     #[allow(clippy::eq_op)]
     #[rustc_diagnostic_item = "f16_nan"]
     #[unstable(feature = "f16", issue = "116909")]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index e473fac0393..c97dbfb63ae 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -470,14 +470,16 @@ impl f32 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE 754 doesn't define just a single NaN value;
-    /// a plethora of bit patterns are considered to be NaN.
-    /// Furthermore, the standard makes a difference
-    /// between a "signaling" and a "quiet" NaN,
-    /// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
-    /// This constant isn't guaranteed to equal to any specific NaN bitpattern,
-    /// and the stability of its representation over Rust versions
-    /// and target platforms isn't guaranteed.
+    /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
+    /// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
+    /// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
+    /// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
+    /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
+    /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
+    /// The concrete bit pattern may change across Rust versions and target platforms.
     #[stable(feature = "assoc_int_consts", since = "1.43.0")]
     #[rustc_diagnostic_item = "f32_nan"]
     #[allow(clippy::eq_op)]
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 6522a80b0b7..91affdb3794 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -469,14 +469,16 @@ impl f64 {
 
     /// Not a Number (NaN).
     ///
-    /// Note that IEEE 754 doesn't define just a single NaN value;
-    /// a plethora of bit patterns are considered to be NaN.
-    /// Furthermore, the standard makes a difference
-    /// between a "signaling" and a "quiet" NaN,
-    /// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
-    /// This constant isn't guaranteed to equal to any specific NaN bitpattern,
-    /// and the stability of its representation over Rust versions
-    /// and target platforms isn't guaranteed.
+    /// Note that IEEE 754 doesn't define just a single NaN value; a plethora of bit patterns are
+    /// considered to be NaN. Furthermore, the standard makes a difference between a "signaling" and
+    /// a "quiet" NaN, and allows inspecting its "payload" (the unspecified bits in the bit pattern)
+    /// and its sign. See the [specification of NaN bit patterns](f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// This constant is guaranteed to be a quiet NaN (on targets that follow the Rust assumptions
+    /// that the quiet/signaling bit being set to 1 indicates a quiet NaN). Beyond that, nothing is
+    /// guaranteed about the specific bit pattern chosen here: both payload and sign are arbitrary.
+    /// The concrete bit pattern may change across Rust versions and target platforms.
     #[rustc_diagnostic_item = "f64_nan"]
     #[stable(feature = "assoc_int_consts", since = "1.43.0")]
     #[allow(clippy::eq_op)]
diff --git a/library/coretests/tests/hint.rs b/library/coretests/tests/hint.rs
new file mode 100644
index 00000000000..032bbc1dcc8
--- /dev/null
+++ b/library/coretests/tests/hint.rs
@@ -0,0 +1,23 @@
+#[test]
+fn select_unpredictable_drop() {
+    use core::cell::Cell;
+    struct X<'a>(&'a Cell<bool>);
+    impl Drop for X<'_> {
+        fn drop(&mut self) {
+            self.0.set(true);
+        }
+    }
+
+    let a_dropped = Cell::new(false);
+    let b_dropped = Cell::new(false);
+    let a = X(&a_dropped);
+    let b = X(&b_dropped);
+    assert!(!a_dropped.get());
+    assert!(!b_dropped.get());
+    let selected = core::hint::select_unpredictable(core::hint::black_box(true), a, b);
+    assert!(!a_dropped.get());
+    assert!(b_dropped.get());
+    drop(selected);
+    assert!(a_dropped.get());
+    assert!(b_dropped.get());
+}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 7ad154796f6..1c43bfe0ed4 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -68,6 +68,7 @@
 #![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
+#![feature(select_unpredictable)]
 #![feature(slice_from_ptr_range)]
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
@@ -147,6 +148,7 @@ mod ffi;
 mod fmt;
 mod future;
 mod hash;
+mod hint;
 mod intrinsics;
 mod io;
 mod iter;
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 6b70ff764d7..917a470842c 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.153" }
+compiler_builtins = { version = "=0.1.155" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index e157ff233bb..b70d452b427 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasnโ€™t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/138784
+Last change is for: https://github.com/rust-lang/rust/pull/139931
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 69a8bd59f16..6e84b83d17d 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -370,8 +370,8 @@ impl Step for Llvm {
             cfg.define("LLVM_PROFDATA_FILE", path);
         }
 
-        // Libraries for ELF section compression.
-        if !target.is_windows() {
+        // Libraries for ELF section compression and profraw files merging.
+        if !target.is_msvc() {
             cfg.define("LLVM_ENABLE_ZLIB", "ON");
         } else {
             cfg.define("LLVM_ENABLE_ZLIB", "OFF");
diff --git a/src/build_helper/src/fs/mod.rs b/src/build_helper/src/fs/mod.rs
index 02029846fd1..123df76e6a2 100644
--- a/src/build_helper/src/fs/mod.rs
+++ b/src/build_helper/src/fs/mod.rs
@@ -22,21 +22,27 @@ where
 /// A wrapper around [`std::fs::remove_dir_all`] that can also be used on *non-directory entries*,
 /// including files and symbolic links.
 ///
-/// - This will produce an error if the target path is not found.
+/// - This will not produce an error if the target path is not found.
 /// - Like [`std::fs::remove_dir_all`], this helper does not traverse symbolic links, will remove
 ///   symbolic link itself.
 /// - This helper is **not** robust against races on the underlying filesystem, behavior is
 ///   unspecified if this helper is called concurrently.
 /// - This helper is not robust against TOCTOU problems.
 ///
-/// FIXME: this implementation is insufficiently robust to replace bootstrap's clean `rm_rf`
-/// implementation:
-///
-/// - This implementation currently does not perform retries.
+/// FIXME: Audit whether this implementation is robust enough to replace bootstrap's clean `rm_rf`.
 #[track_caller]
 pub fn recursive_remove<P: AsRef<Path>>(path: P) -> io::Result<()> {
     let path = path.as_ref();
-    let metadata = fs::symlink_metadata(path)?;
+
+    // If the path doesn't exist, we treat it as a successful no-op.
+    // From the caller's perspective, the goal is simply "ensure this file/dir is gone" โ€”
+    // if it's already not there, that's a success, not an error.
+    let metadata = match fs::symlink_metadata(path) {
+        Ok(m) => m,
+        Err(e) if e.kind() == io::ErrorKind::NotFound => return Ok(()),
+        Err(e) => return Err(e),
+    };
+
     #[cfg(windows)]
     let is_dir_like = |meta: &fs::Metadata| {
         use std::os::windows::fs::FileTypeExt;
@@ -45,11 +51,35 @@ pub fn recursive_remove<P: AsRef<Path>>(path: P) -> io::Result<()> {
     #[cfg(not(windows))]
     let is_dir_like = fs::Metadata::is_dir;
 
-    if is_dir_like(&metadata) {
-        fs::remove_dir_all(path)
-    } else {
-        try_remove_op_set_perms(fs::remove_file, path, metadata)
+    const MAX_RETRIES: usize = 5;
+    const RETRY_DELAY_MS: u64 = 100;
+
+    let try_remove = || {
+        if is_dir_like(&metadata) {
+            fs::remove_dir_all(path)
+        } else {
+            try_remove_op_set_perms(fs::remove_file, path, metadata.clone())
+        }
+    };
+
+    // Retry deletion a few times to handle transient filesystem errors.
+    // This is unusual for local file operations, but it's a mitigation
+    // against unlikely events where malware scanners may be holding a
+    // file beyond our control, to give the malware scanners some opportunity
+    // to release their hold.
+    for attempt in 0..MAX_RETRIES {
+        match try_remove() {
+            Ok(()) => return Ok(()),
+            Err(e) if e.kind() == io::ErrorKind::NotFound => return Ok(()),
+            Err(_) if attempt < MAX_RETRIES - 1 => {
+                std::thread::sleep(std::time::Duration::from_millis(RETRY_DELAY_MS));
+                continue;
+            }
+            Err(e) => return Err(e),
+        }
     }
+
+    Ok(())
 }
 
 fn try_remove_op_set_perms<'p, Op>(mut op: Op, path: &'p Path, metadata: Metadata) -> io::Result<()>
@@ -67,3 +97,9 @@ where
         Err(e) => Err(e),
     }
 }
+
+pub fn remove_and_create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    let path = path.as_ref();
+    recursive_remove(path)?;
+    fs::create_dir_all(path)
+}
diff --git a/src/build_helper/src/fs/tests.rs b/src/build_helper/src/fs/tests.rs
index 1e694393127..7ce1d8928d1 100644
--- a/src/build_helper/src/fs/tests.rs
+++ b/src/build_helper/src/fs/tests.rs
@@ -14,7 +14,7 @@ mod recursive_remove_tests {
         let tmpdir = env::temp_dir();
         let path = tmpdir.join("__INTERNAL_BOOTSTRAP_nonexistent_path");
         assert!(fs::symlink_metadata(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound));
-        assert!(recursive_remove(&path).is_err_and(|e| e.kind() == io::ErrorKind::NotFound));
+        assert!(recursive_remove(&path).is_ok());
     }
 
     #[test]
diff --git a/src/doc/rustc-dev-guide/src/tests/best-practices.md b/src/doc/rustc-dev-guide/src/tests/best-practices.md
index 6905ee13283..2bdc7f3a243 100644
--- a/src/doc/rustc-dev-guide/src/tests/best-practices.md
+++ b/src/doc/rustc-dev-guide/src/tests/best-practices.md
@@ -175,6 +175,8 @@ See [compiletest directives] for a listing of directives.
 - For `ignore-*`/`needs-*`/`only-*` directives, unless extremely obvious,
   provide a brief remark on why the directive is needed. E.g. `"//@ ignore-wasi
   (wasi codegens the main symbol differently)"`.
+- When using `//@ ignore-auxiliary`, specify the corresponding main test files,
+  e.g. ``//@ ignore-auxiliary (used by `./foo.rs`)``.
 
 ## FileCheck best practices
 
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 0aad8be982f..dae659e6317 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -124,6 +124,9 @@ means the test won't be compiled or run.
 * `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below)
 * `only-X` is like `ignore-X`, but will *only* run the test on that target or
   stage
+* `ignore-auxiliary` is intended for files that *participate* in one or more other
+  main test files but that `compiletest` should not try to build the file itself.
+  Please backlink to which main test is actually using the auxiliary file.
 * `ignore-test` always ignores the test. This can be used to temporarily disable
   a test if it is currently not working, but you want to keep it in tree to
   re-enable it later.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 2f6870e3c36..55a116a018a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -67,9 +67,13 @@ pub(crate) fn try_inline(
             record_extern_fqn(cx, did, ItemType::Trait);
             cx.with_param_env(did, |cx| {
                 build_impls(cx, did, attrs_without_docs, &mut ret);
-                clean::TraitItem(Box::new(build_external_trait(cx, did)))
+                clean::TraitItem(Box::new(build_trait(cx, did)))
             })
         }
+        Res::Def(DefKind::TraitAlias, did) => {
+            record_extern_fqn(cx, did, ItemType::TraitAlias);
+            cx.with_param_env(did, |cx| clean::TraitAliasItem(build_trait_alias(cx, did)))
+        }
         Res::Def(DefKind::Fn, did) => {
             record_extern_fqn(cx, did, ItemType::Function);
             cx.with_param_env(did, |cx| {
@@ -251,7 +255,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
     }
 }
 
-pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
+pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
     let trait_items = cx
         .tcx
         .associated_items(did)
@@ -263,11 +267,18 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean
     let predicates = cx.tcx.predicates_of(did);
     let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
     let generics = filter_non_trait_generics(did, generics);
-    let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
+    let (generics, supertrait_bounds) = separate_self_bounds(generics);
     clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds }
 }
 
-pub(crate) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
+fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias {
+    let predicates = cx.tcx.predicates_of(did);
+    let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
+    let (generics, bounds) = separate_self_bounds(generics);
+    clean::TraitAlias { generics, bounds }
+}
+
+pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clean::Function> {
     let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
     // The generics need to be cleaned before the signature.
     let mut generics =
@@ -788,12 +799,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
     g
 }
 
-/// Supertrait bounds for a trait are also listed in the generics coming from
-/// the metadata for a crate, so we want to separate those out and create a new
-/// list of explicit supertrait bounds to render nicely.
-fn separate_supertrait_bounds(
-    mut g: clean::Generics,
-) -> (clean::Generics, Vec<clean::GenericBound>) {
+fn separate_self_bounds(mut g: clean::Generics) -> (clean::Generics, Vec<clean::GenericBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| match *pred {
         clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
@@ -806,22 +812,17 @@ fn separate_supertrait_bounds(
 }
 
 pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
-    if did.is_local() {
-        return;
-    }
-
+    if did.is_local()
+        || cx.external_traits.contains_key(&did)
+        || cx.active_extern_traits.contains(&did)
     {
-        if cx.external_traits.contains_key(&did) || cx.active_extern_traits.contains(&did) {
-            return;
-        }
+        return;
     }
 
-    {
-        cx.active_extern_traits.insert(did);
-    }
+    cx.active_extern_traits.insert(did);
 
     debug!("record_extern_trait: {did:?}");
-    let trait_ = build_external_trait(cx, did);
+    let trait_ = build_trait(cx, did);
 
     cx.external_traits.insert(did, trait_);
     cx.active_extern_traits.remove(&did);
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index c4dea79370d..41688b41c6e 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -27,7 +27,7 @@ use rustc_span::source_map;
 use rustc_span::symbol::sym;
 use tracing::{debug, info};
 
-use crate::clean::inline::build_external_trait;
+use crate::clean::inline::build_trait;
 use crate::clean::{self, ItemId};
 use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
 use crate::formats::cache::Cache;
@@ -385,7 +385,7 @@ pub(crate) fn run_global_ctxt(
     //
     // Note that in case of `#![no_core]`, the trait is not available.
     if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
-        let sized_trait = build_external_trait(&mut ctxt, sized_trait_did);
+        let sized_trait = build_trait(&mut ctxt, sized_trait_did);
         ctxt.external_traits.insert(sized_trait_did, sized_trait);
     }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 45cb0adecf3..39a631b637b 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1232,12 +1232,13 @@ fn item_trait_alias(
         wrap_item(w, |w| {
             write!(
                 w,
-                "{attrs}trait {name}{generics}{where_b} = {bounds};",
+                "{attrs}trait {name}{generics} = {bounds}{where_clause};",
                 attrs = render_attributes_in_pre(it, "", cx),
                 name = it.name.unwrap(),
                 generics = t.generics.print(cx),
-                where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline).maybe_display(),
                 bounds = bounds(&t.bounds, true, cx),
+                where_clause =
+                    print_where_clause(&t.generics, cx, 0, Ending::NoNewline).maybe_display(),
             )
         })?;
 
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 086a8a67456..44c52c8c766 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -44,6 +44,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-arm-unknown-linux-gnueabihf",
     "ignore-arm-unknown-linux-musleabi",
     "ignore-arm-unknown-linux-musleabihf",
+    "ignore-auxiliary",
     "ignore-avr",
     "ignore-beta",
     "ignore-cdb",
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
index c369fff97f4..f1f1384afb9 100644
--- a/src/tools/compiletest/src/header/cfg.rs
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -101,6 +101,10 @@ fn parse_cfg_name_directive<'a>(
         message: "always"
     }
     condition! {
+        name: "auxiliary",
+        message: "used by another main test file"
+    }
+    condition! {
         name: &config.target,
         allowed_names: &target_cfgs.all_targets,
         message: "when the target is {name}"
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 3a8c3748de9..2525e0adc83 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -940,3 +940,9 @@ fn test_supported_crate_types() {
         "//@ needs-crate-type: bin, cdylib, dylib, lib, proc-macro, rlib, staticlib"
     ));
 }
+
+#[test]
+fn test_ignore_auxiliary() {
+    let config = cfg().build();
+    assert!(check_ignore(&config, "//@ ignore-auxiliary"));
+}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index eb298060b2e..d11f5c1a3a6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -9,6 +9,7 @@ use std::process::{Child, Command, ExitStatus, Output, Stdio};
 use std::sync::Arc;
 use std::{env, iter, str};
 
+use build_helper::fs::remove_and_create_dir_all;
 use camino::{Utf8Path, Utf8PathBuf};
 use colored::Colorize;
 use regex::{Captures, Regex};
@@ -207,12 +208,6 @@ pub fn compute_stamp_hash(config: &Config) -> String {
     format!("{:x}", hash.finish())
 }
 
-fn remove_and_create_dir_all(path: &Utf8Path) {
-    let path = path.as_std_path();
-    let _ = fs::remove_dir_all(path);
-    fs::create_dir_all(path).unwrap();
-}
-
 #[derive(Copy, Clone, Debug)]
 struct TestCx<'test> {
     config: &'test Config,
@@ -523,7 +518,9 @@ impl<'test> TestCx<'test> {
         let mut rustc = Command::new(&self.config.rustc_path);
 
         let out_dir = self.output_base_name().with_extension("pretty-out");
-        remove_and_create_dir_all(&out_dir);
+        remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {
+            panic!("failed to remove and recreate output directory `{out_dir}`: {e}")
+        });
 
         let target = if self.props.force_host { &*self.config.host } else { &*self.config.target };
 
@@ -1098,13 +1095,19 @@ impl<'test> TestCx<'test> {
         let aux_dir = self.aux_output_dir_name();
 
         if !self.props.aux.builds.is_empty() {
-            remove_and_create_dir_all(&aux_dir);
+            remove_and_create_dir_all(&aux_dir).unwrap_or_else(|e| {
+                panic!("failed to remove and recreate output directory `{aux_dir}`: {e}")
+            });
         }
 
         if !self.props.aux.bins.is_empty() {
             let aux_bin_dir = self.aux_bin_output_dir_name();
-            remove_and_create_dir_all(&aux_dir);
-            remove_and_create_dir_all(&aux_bin_dir);
+            remove_and_create_dir_all(&aux_dir).unwrap_or_else(|e| {
+                panic!("failed to remove and recreate output directory `{aux_dir}`: {e}")
+            });
+            remove_and_create_dir_all(&aux_bin_dir).unwrap_or_else(|e| {
+                panic!("failed to remove and recreate output directory `{aux_bin_dir}`: {e}")
+            });
         }
 
         aux_dir
@@ -1509,7 +1512,9 @@ impl<'test> TestCx<'test> {
 
         let set_mir_dump_dir = |rustc: &mut Command| {
             let mir_dump_dir = self.get_mir_dump_dir();
-            remove_and_create_dir_all(&mir_dump_dir);
+            remove_and_create_dir_all(&mir_dump_dir).unwrap_or_else(|e| {
+                panic!("failed to remove and recreate output directory `{mir_dump_dir}`: {e}")
+            });
             let mut dir_opt = "-Zdump-mir-dir=".to_string();
             dir_opt.push_str(mir_dump_dir.as_str());
             debug!("dir_opt: {:?}", dir_opt);
@@ -1969,7 +1974,9 @@ impl<'test> TestCx<'test> {
         let suffix =
             self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
         let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix));
-        remove_and_create_dir_all(&compare_dir);
+        remove_and_create_dir_all(&compare_dir).unwrap_or_else(|e| {
+            panic!("failed to remove and recreate output directory `{compare_dir}`: {e}")
+        });
 
         // We need to create a new struct for the lifetimes on `config` to work.
         let new_rustdoc = TestCx {
diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs
index 2583ae96a67..637ea833357 100644
--- a/src/tools/compiletest/src/runtest/rustdoc.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc.rs
@@ -7,7 +7,9 @@ impl TestCx<'_> {
         assert!(self.revision.is_none(), "revisions not relevant here");
 
         let out_dir = self.output_base_dir();
-        remove_and_create_dir_all(&out_dir);
+        remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {
+            panic!("failed to remove and recreate output directory `{out_dir}`: {e}")
+        });
 
         let proc_res = self.document(&out_dir, &self.testpaths);
         if !proc_res.status.success() {
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index bf7eb2e109a..9f88faca892 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -9,7 +9,9 @@ impl TestCx<'_> {
         assert!(self.revision.is_none(), "revisions not relevant here");
 
         let out_dir = self.output_base_dir();
-        remove_and_create_dir_all(&out_dir);
+        remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {
+            panic!("failed to remove and recreate output directory `{out_dir}`: {e}")
+        });
 
         let proc_res = self.document(&out_dir, &self.testpaths);
         if !proc_res.status.success() {
diff --git a/src/tools/miri/tests/pass/tls/tls_leak_main_thread_allowed.rs b/src/tools/miri/tests/pass/tls/tls_leak_main_thread_allowed.rs
index 341b2280e01..abc0968f7c4 100644
--- a/src/tools/miri/tests/pass/tls/tls_leak_main_thread_allowed.rs
+++ b/src/tools/miri/tests/pass/tls/tls_leak_main_thread_allowed.rs
@@ -13,7 +13,7 @@ pub fn main() {
     TLS.set(Some(Box::leak(Box::new(123))));
 
     // We can only ignore leaks on targets that use `#[thread_local]` statics to implement
-    // `thread_local!`. Ignore the test on targest that don't.
+    // `thread_local!`. Ignore the test on targets that don't.
     if cfg!(target_thread_local) {
         thread_local! {
             static TLS_KEY: Cell<Option<&'static i32>> = Cell::new(None);
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index 90d0ca717b2..9342d164be4 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -25,6 +25,7 @@ pub struct Environment {
     prebuilt_rustc_perf: Option<Utf8PathBuf>,
     use_bolt: bool,
     shared_llvm: bool,
+    run_tests: bool,
 }
 
 impl Environment {
@@ -101,6 +102,10 @@ impl Environment {
     pub fn benchmark_cargo_config(&self) -> &[String] {
         &self.benchmark_cargo_config
     }
+
+    pub fn run_tests(&self) -> bool {
+        self.run_tests
+    }
 }
 
 /// What is the extension of binary executables on this platform?
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index ff4ddbaea49..d5e6640fb43 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -94,6 +94,10 @@ enum EnvironmentCmd {
         /// Arguments passed to `rustc-perf --cargo-config <value>` when running benchmarks.
         #[arg(long)]
         benchmark_cargo_config: Vec<String>,
+
+        /// Perform tests after final build if it's not a try build
+        #[arg(long)]
+        run_tests: bool,
     },
     /// Perform an optimized build on Linux CI, from inside Docker.
     LinuxCi {
@@ -125,6 +129,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
             skipped_tests,
             benchmark_cargo_config,
             shared,
+            run_tests,
         } => {
             let env = EnvironmentBuilder::default()
                 .host_tuple(target_triple)
@@ -138,6 +143,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .use_bolt(use_bolt)
                 .skipped_tests(skipped_tests)
                 .benchmark_cargo_config(benchmark_cargo_config)
+                .run_tests(run_tests)
                 .build()?;
 
             (env, shared.build_args)
@@ -160,6 +166,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 // FIXME: Enable bolt for aarch64 once it's fixed upstream. Broken as of December 2024.
                 .use_bolt(!is_aarch64)
                 .skipped_tests(vec![])
+                .run_tests(true)
                 .build()?;
 
             (env, shared.build_args)
@@ -179,6 +186,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .shared_llvm(false)
                 .use_bolt(false)
                 .skipped_tests(vec![])
+                .run_tests(true)
                 .build()?;
 
             (env, shared.build_args)
@@ -344,7 +352,7 @@ fn execute_pipeline(
     // possible regressions.
     // The tests are not executed for try builds, which can be in various broken states, so we don't
     // want to gatekeep them with tests.
-    if !is_try_build() {
+    if !is_try_build() && env.run_tests() {
         timer.section("Run tests", |_| run_tests(env))?;
     }
 
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index f9beffec750..15ed03ad5c2 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -14,9 +14,5 @@ build_helper = { path = "../../build_helper" }
 serde_json = "1.0"
 libc = "0.2"
 
-# FIXME(#137532): replace `os_pipe` with `anonymous_pipe` once it stabilizes and
-# reaches beta.
-os_pipe = "1.2.1"
-
 [lib]
 crate-type = ["lib", "dylib"]
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index c75d500d2f0..f37b38ac0b1 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -41,8 +41,6 @@ pub use bstr;
 pub use gimli;
 pub use libc;
 pub use object;
-// FIXME(#137532): replace with std `anonymous_pipe` once it stabilizes and reaches beta.
-pub use os_pipe;
 pub use regex;
 pub use serde_json;
 pub use similar;
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 745a8097c8a..2dbb3f5d69c 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -902,9 +902,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.172"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
 
 [[package]]
 name = "libloading"
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index fd8e4eacc0f..dd7f9c6b146 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -260,7 +260,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "constant_time_eq",
     "cpufeatures",
     "crc32fast",
-    "crossbeam-channel",
     "crossbeam-deque",
     "crossbeam-epoch",
     "crossbeam-utils",
@@ -295,7 +294,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "gimli",
     "gsgdt",
     "hashbrown",
-    "hermit-abi",
     "icu_list",
     "icu_list_data",
     "icu_locid",
@@ -329,7 +327,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "miniz_oxide",
     "nix",
     "nu-ansi-term",
-    "num_cpus",
     "object",
     "odht",
     "once_cell",
diff --git a/tests/assembly/cstring-merging.rs b/tests/assembly/cstring-merging.rs
index b5c530ac35d..f7d0775f7af 100644
--- a/tests/assembly/cstring-merging.rs
+++ b/tests/assembly/cstring-merging.rs
@@ -1,3 +1,5 @@
+// MIPS assembler uses the label prefix `$anon.` for local anonymous variables
+// other architectures (including ARM and x86-64) use the prefix `.Lanon.`
 //@ only-linux
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -Copt-level=3
@@ -6,13 +8,13 @@
 use std::ffi::CStr;
 
 // CHECK: .section .rodata.str1.{{[12]}},"aMS"
-// CHECK: .Lanon.{{.+}}:
+// CHECK: {{(\.L|\$)}}anon.{{.+}}:
 // CHECK-NEXT: .asciz "foo"
 #[unsafe(no_mangle)]
 static CSTR: &[u8; 4] = b"foo\0";
 
 // CHECK-NOT: .section
-// CHECK: .Lanon.{{.+}}:
+// CHECK: {{(\.L|\$)}}anon.{{.+}}:
 // CHECK-NEXT: .asciz "bar"
 #[unsafe(no_mangle)]
 pub fn cstr() -> &'static CStr {
@@ -20,7 +22,7 @@ pub fn cstr() -> &'static CStr {
 }
 
 // CHECK-NOT: .section
-// CHECK: .Lanon.{{.+}}:
+// CHECK: {{(\.L|\$)}}anon.{{.+}}:
 // CHECK-NEXT: .asciz "baz"
 #[unsafe(no_mangle)]
 pub fn manual_cstr() -> &'static str {
diff --git a/tests/codegen/autodiffv2.rs b/tests/codegen/autodiffv2.rs
new file mode 100644
index 00000000000..a40d19d3be3
--- /dev/null
+++ b/tests/codegen/autodiffv2.rs
@@ -0,0 +1,113 @@
+//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+//
+// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many
+// breakages. One benefit is that we match the IR generated by Enzyme only after running it
+// through LLVM's O3 pipeline, which will remove most of the noise.
+// However, our integration test could also be affected by changes in how rustc lowers MIR into
+// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should
+// reduce this test to only match the first lines and the ret instructions.
+//
+// The function tested here has 4 inputs and 5 outputs, so we could either call forward-mode
+// autodiff 4 times, or reverse mode 5 times. Since a forward-mode call is usually faster than
+// reverse mode, we prefer it here. This file also tests a new optimization (batch mode), which
+// allows us to call forward-mode autodiff only once, and get all 5 outputs in a single call.
+//
+// We support 2 different batch modes. `d_square2` has the same interface as scalar forward-mode,
+// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
+// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
+// original function arguments.
+//
+// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
+// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
+// try to rewrite the dummy functions later. We should consider to change to pure declarations both
+// in our frontend and in the llvm backend to avoid these issues.
+
+#![feature(autodiff)]
+
+use std::autodiff::autodiff;
+
+#[no_mangle]
+//#[autodiff(d_square1, Forward, Dual, Dual)]
+#[autodiff(d_square2, Forward, 4, Dualv, Dualv)]
+#[autodiff(d_square3, Forward, 4, Dual, Dual)]
+fn square(x: &[f32], y: &mut [f32]) {
+    assert!(x.len() >= 4);
+    assert!(y.len() >= 5);
+    y[0] = 4.3 * x[0] + 1.2 * x[1] + 3.4 * x[2] + 2.1 * x[3];
+    y[1] = 2.3 * x[0] + 4.5 * x[1] + 1.7 * x[2] + 6.4 * x[3];
+    y[2] = 1.1 * x[0] + 3.3 * x[1] + 2.5 * x[2] + 4.7 * x[3];
+    y[3] = 5.2 * x[0] + 1.4 * x[1] + 2.6 * x[2] + 3.8 * x[3];
+    y[4] = 1.0 * x[0] + 2.0 * x[1] + 3.0 * x[2] + 4.0 * x[3];
+}
+
+fn main() {
+    let x1 = std::hint::black_box(vec![0.0, 1.0, 2.0, 3.0]);
+
+    let dx1 = std::hint::black_box(vec![1.0; 12]);
+
+    let z1 = std::hint::black_box(vec![1.0, 0.0, 0.0, 0.0]);
+    let z2 = std::hint::black_box(vec![0.0, 1.0, 0.0, 0.0]);
+    let z3 = std::hint::black_box(vec![0.0, 0.0, 1.0, 0.0]);
+    let z4 = std::hint::black_box(vec![0.0, 0.0, 0.0, 1.0]);
+
+    let z5 = std::hint::black_box(vec![
+        1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
+    ]);
+
+    let mut y1 = std::hint::black_box(vec![0.0; 5]);
+    let mut y2 = std::hint::black_box(vec![0.0; 5]);
+    let mut y3 = std::hint::black_box(vec![0.0; 5]);
+    let mut y4 = std::hint::black_box(vec![0.0; 5]);
+
+    let mut y5 = std::hint::black_box(vec![0.0; 5]);
+
+    let mut y6 = std::hint::black_box(vec![0.0; 5]);
+
+    let mut dy1_1 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy1_2 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy1_3 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy1_4 = std::hint::black_box(vec![0.0; 5]);
+
+    let mut dy2 = std::hint::black_box(vec![0.0; 20]);
+
+    let mut dy3_1 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy3_2 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy3_3 = std::hint::black_box(vec![0.0; 5]);
+    let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);
+
+    // scalar.
+    //d_square1(&x1, &z1, &mut y1, &mut dy1_1);
+    //d_square1(&x1, &z2, &mut y2, &mut dy1_2);
+    //d_square1(&x1, &z3, &mut y3, &mut dy1_3);
+    //d_square1(&x1, &z4, &mut y4, &mut dy1_4);
+
+    // assert y1 == y2 == y3 == y4
+    //for i in 0..5 {
+    //    assert_eq!(y1[i], y2[i]);
+    //    assert_eq!(y1[i], y3[i]);
+    //    assert_eq!(y1[i], y4[i]);
+    //}
+
+    // batch mode A)
+    d_square2(&x1, &z5, &mut y5, &mut dy2);
+
+    // assert y1 == y2 == y3 == y4 == y5
+    //for i in 0..5 {
+    //    assert_eq!(y1[i], y5[i]);
+    //}
+
+    // batch mode B)
+    d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);
+    for i in 0..5 {
+        assert_eq!(y5[i], y6[i]);
+    }
+
+    for i in 0..5 {
+        assert_eq!(dy2[0..5][i], dy3_1[i]);
+        assert_eq!(dy2[5..10][i], dy3_2[i]);
+        assert_eq!(dy2[10..15][i], dy3_3[i]);
+        assert_eq!(dy2[15..20][i], dy3_4[i]);
+    }
+}
diff --git a/tests/codegen/issues/issue-101082.rs b/tests/codegen/issues/issue-101082.rs
index 96cdff64dda..8d15921ddb4 100644
--- a/tests/codegen/issues/issue-101082.rs
+++ b/tests/codegen/issues/issue-101082.rs
@@ -12,6 +12,7 @@
 // at the time still sometimes fails, so only verify it for the power-of-two size
 // - https://github.com/llvm/llvm-project/issues/134735
 //@[x86-64-v3] only-x86_64
+//@[x86-64-v3] min-llvm-version: 21
 //@[x86-64-v3] compile-flags: -Ctarget-cpu=x86-64-v3
 
 #![crate_type = "lib"]
@@ -19,16 +20,7 @@
 #[no_mangle]
 pub fn test() -> usize {
     // CHECK-LABEL: @test(
-    // host: ret {{i64|i32}} 165
-    // x86-64: ret {{i64|i32}} 165
-
-    // FIXME: Now that this autovectorizes via a masked load, it doesn't actually
-    // const-fold for certain widths.  The `test_eight` case below shows that, yes,
-    // what we're emitting *can* be const-folded, except that the way LLVM does it
-    // for certain widths doesn't today.  We should be able to put this back to
-    // the same check after <https://github.com/llvm/llvm-project/issues/134513>
-    // x86-64-v3: masked.load
-
+    // CHECK: ret {{i64|i32}} 165
     let values = [23, 16, 54, 3, 60, 9];
     let mut acc = 0;
     for item in values {
diff --git a/tests/codegen/remap_path_prefix/aux_mod.rs b/tests/codegen/remap_path_prefix/aux_mod.rs
index c37e91c705c..3217e9e51e7 100644
--- a/tests/codegen/remap_path_prefix/aux_mod.rs
+++ b/tests/codegen/remap_path_prefix/aux_mod.rs
@@ -1,4 +1,4 @@
-//@ ignore-test: this is not a test
+//@ ignore-auxiliary (used by `./main.rs`)
 
 #[inline]
 pub fn some_aux_mod_function() -> i32 {
diff --git a/tests/crashes/100618.rs b/tests/crashes/100618.rs
deleted file mode 100644
index 911c4098bad..00000000000
--- a/tests/crashes/100618.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #100618
-//@ compile-flags: -Cdebuginfo=2
-
-//@ only-x86_64
-enum Foo<T: 'static> {
-    Value(T),
-    Recursive(&'static Foo<Option<T>>),
-}
-
-fn main() {
-    let _x = Foo::Value(());
-}
diff --git a/tests/crashes/115994.rs b/tests/crashes/115994.rs
deleted file mode 100644
index 23d1507136f..00000000000
--- a/tests/crashes/115994.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #115994
-//@ compile-flags: -Cdebuginfo=2 --crate-type lib
-
-// To prevent "overflow while adding drop-check rules".
-use std::mem::ManuallyDrop;
-
-pub enum Foo<U> {
-    Leaf(U),
-
-    Branch(BoxedFoo<BoxedFoo<U>>),
-}
-
-pub type BoxedFoo<U> = ManuallyDrop<Box<Foo<U>>>;
-
-pub fn test() -> Foo<usize> {
-    todo!()
-}
diff --git a/tests/crashes/121538.rs b/tests/crashes/121538.rs
deleted file mode 100644
index f18bad84b57..00000000000
--- a/tests/crashes/121538.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//@ known-bug: #121538
-//@ compile-flags: -Cdebuginfo=2
-
-use std::marker::PhantomData;
-
-struct Digit<T> {
-    elem: T
-}
-
-struct Node<T:'static> { m: PhantomData<&'static T> }
-
-enum FingerTree<T:'static> {
-    Single(T),
-
-    Deep(
-        Digit<T>,
-        Node<FingerTree<Node<T>>>,
-        )
-}
-
-enum Wrapper<T:'static> {
-    Simple,
-    Other(FingerTree<T>),
-}
-
-fn main() {
-    let w =
-        Some(Wrapper::Simple::<u32>);
-
-}
diff --git a/tests/debuginfo/drop-locations.rs b/tests/debuginfo/drop-locations.rs
index a55cf7b50a8..91b3da5c34a 100644
--- a/tests/debuginfo/drop-locations.rs
+++ b/tests/debuginfo/drop-locations.rs
@@ -1,5 +1,7 @@
 //@ ignore-android
-//@ ignore-test: #128971
+
+// FIXME: stepping with "next" in a debugger skips past end-of-scope drops
+//@ ignore-test (broken, see #128971)
 
 #![allow(unused)]
 
diff --git a/tests/debuginfo/recursive-enum.rs b/tests/debuginfo/recursive-enum.rs
index c2c3e71b8a4..b861e6d617c 100644
--- a/tests/debuginfo/recursive-enum.rs
+++ b/tests/debuginfo/recursive-enum.rs
@@ -4,7 +4,7 @@
 // gdb-command:run
 
 // Test whether compiling a recursive enum definition crashes debug info generation. The test case
-// is taken from issue #11083.
+// is taken from issue #11083 and #135093.
 
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
@@ -18,6 +18,21 @@ struct WindowCallbacks<'a> {
     pos_callback: Option<Box<FnMut(&Window, i32, i32) + 'a>>,
 }
 
+enum ExpandingRecursive<T> {
+    Recurse(Indirect<T>),
+    Item(T),
+}
+
+struct Indirect<U> {
+    rec: *const ExpandingRecursive<Option<U>>,
+}
+
+
 fn main() {
     let x = WindowCallbacks { pos_callback: None };
+
+    // EXPANDING RECURSIVE
+    let expanding_recursive: ExpandingRecursive<u64> = ExpandingRecursive::Recurse(Indirect {
+        rec: &ExpandingRecursive::Item(Option::Some(42)),
+    });
 }
diff --git a/tests/crashes/107362.rs b/tests/debuginfo/recursive-type-with-gat.rs
index 8d55d611eb1..b8a67d8d24b 100644
--- a/tests/crashes/107362.rs
+++ b/tests/debuginfo/recursive-type-with-gat.rs
@@ -1,4 +1,3 @@
-//@ known-bug: #107362
 //@ compile-flags: -Cdebuginfo=2
 
 pub trait Functor
diff --git a/tests/run-make/broken-pipe-no-ice/rmake.rs b/tests/run-make/broken-pipe-no-ice/rmake.rs
index 3e54b576fd4..0521b395020 100644
--- a/tests/run-make/broken-pipe-no-ice/rmake.rs
+++ b/tests/run-make/broken-pipe-no-ice/rmake.rs
@@ -14,9 +14,7 @@
 use std::io::Read;
 use std::process::{Command, Stdio};
 
-// FIXME(#137532): replace `os_pipe` dependency with std `anonymous_pipe` once that stabilizes and
-// reaches beta.
-use run_make_support::{env_var, os_pipe};
+use run_make_support::env_var;
 
 #[derive(Debug, PartialEq)]
 enum Binary {
@@ -25,7 +23,7 @@ enum Binary {
 }
 
 fn check_broken_pipe_handled_gracefully(bin: Binary, mut cmd: Command) {
-    let (reader, writer) = os_pipe::pipe().unwrap();
+    let (reader, writer) = std::io::pipe().unwrap();
     drop(reader); // close read-end
     cmd.stdout(writer).stderr(Stdio::piped());
 
diff --git a/tests/run-make/print-request-help-stable-unstable/help-diff.diff b/tests/run-make/print-request-help-stable-unstable/help-diff.diff
new file mode 100644
index 00000000000..07eafca3271
--- /dev/null
+++ b/tests/run-make/print-request-help-stable-unstable/help-diff.diff
@@ -0,0 +1,7 @@
+@@ -1,5 +1,5 @@
+ error: unknown print request: `xxx`
+   |
+-  = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models`
++  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
+ 
diff --git a/tests/run-make/print-request-help-stable-unstable/rmake.rs b/tests/run-make/print-request-help-stable-unstable/rmake.rs
new file mode 100644
index 00000000000..a59963da5c4
--- /dev/null
+++ b/tests/run-make/print-request-help-stable-unstable/rmake.rs
@@ -0,0 +1,33 @@
+//! Check that unstable print requests are omitted from help if compiler is in stable channel.
+//!
+//! Issue: <https://github.com/rust-lang/rust/issues/138698>
+use run_make_support::{diff, rustc, similar};
+
+fn main() {
+    let stable_invalid_print_request_help = rustc()
+        .env("RUSTC_BOOTSTRAP", "-1")
+        .cfg("force_stable")
+        .print("xxx")
+        .run_fail()
+        .stderr_utf8();
+    assert!(!stable_invalid_print_request_help.contains("all-target-specs-json"));
+    diff()
+        .expected_file("stable-invalid-print-request-help.err")
+        .actual_text("stable_invalid_print_request_help", &stable_invalid_print_request_help)
+        .run();
+
+    let unstable_invalid_print_request_help = rustc().print("xxx").run_fail().stderr_utf8();
+    assert!(unstable_invalid_print_request_help.contains("all-target-specs-json"));
+    diff()
+        .expected_file("unstable-invalid-print-request-help.err")
+        .actual_text("unstable_invalid_print_request_help", &unstable_invalid_print_request_help)
+        .run();
+
+    let help_diff = similar::TextDiff::from_lines(
+        &stable_invalid_print_request_help,
+        &unstable_invalid_print_request_help,
+    )
+    .unified_diff()
+    .to_string();
+    diff().expected_file("help-diff.diff").actual_text("help_diff", help_diff).run();
+}
diff --git a/tests/run-make/print-request-help-stable-unstable/stable-invalid-print-request-help.err b/tests/run-make/print-request-help-stable-unstable/stable-invalid-print-request-help.err
new file mode 100644
index 00000000000..019a578dad3
--- /dev/null
+++ b/tests/run-make/print-request-help-stable-unstable/stable-invalid-print-request-help.err
@@ -0,0 +1,5 @@
+error: unknown print request: `xxx`
+  |
+  = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models`
+  = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
+
diff --git a/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err
new file mode 100644
index 00000000000..50ef340e3dd
--- /dev/null
+++ b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err
@@ -0,0 +1,5 @@
+error: unknown print request: `xxx`
+  |
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
+
diff --git a/tests/rustdoc/auxiliary/ext-trait-aliases.rs b/tests/rustdoc/auxiliary/ext-trait-aliases.rs
new file mode 100644
index 00000000000..8454c04063c
--- /dev/null
+++ b/tests/rustdoc/auxiliary/ext-trait-aliases.rs
@@ -0,0 +1,13 @@
+#![feature(trait_alias)]
+
+pub trait ExtAlias0 = Copy + Iterator<Item = u8>;
+
+pub trait ExtAlias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
+
+pub trait ExtAlias2<T> = where T: From<String>, String: Into<T>;
+
+pub trait ExtAlias3 = Sized;
+
+pub trait ExtAlias4 = where Self: Sized;
+
+pub trait ExtAlias5 = ;
diff --git a/tests/rustdoc/auxiliary/trait-alias-mention.rs b/tests/rustdoc/auxiliary/trait-alias-mention.rs
deleted file mode 100644
index 6df06c87a09..00000000000
--- a/tests/rustdoc/auxiliary/trait-alias-mention.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![feature(trait_alias)]
-
-pub trait SomeAlias = std::fmt::Debug + std::marker::Copy;
diff --git a/tests/rustdoc/trait-alias-mention.rs b/tests/rustdoc/trait-alias-mention.rs
deleted file mode 100644
index b6ef926e644..00000000000
--- a/tests/rustdoc/trait-alias-mention.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ aux-build:trait-alias-mention.rs
-//@ build-aux-docs
-
-#![crate_name = "foo"]
-
-extern crate trait_alias_mention;
-
-//@ has foo/fn.mention_alias_in_bounds.html '//a[@href="../trait_alias_mention/traitalias.SomeAlias.html"]' 'SomeAlias'
-pub fn mention_alias_in_bounds<T: trait_alias_mention::SomeAlias>() {
-}
diff --git a/tests/rustdoc/trait-aliases.rs b/tests/rustdoc/trait-aliases.rs
new file mode 100644
index 00000000000..1be93f72042
--- /dev/null
+++ b/tests/rustdoc/trait-aliases.rs
@@ -0,0 +1,82 @@
+// Basic testing for trait aliases.
+#![feature(trait_alias)]
+#![crate_name = "it"]
+
+// Check the "local case" (HIR cleaning) //
+
+//@ has it/all.html '//a[@href="traitalias.Alias0.html"]' 'Alias0'
+//@ has it/index.html '//h2[@id="trait-aliases"]' 'Trait Aliases'
+//@ has it/index.html '//a[@class="traitalias"]' 'Alias0'
+//@ has it/traitalias.Alias0.html
+//@ has - '//*[@class="rust item-decl"]//code' 'trait Alias0 = Copy + Iterator<Item = u8>;'
+pub trait Alias0 = Copy + Iterator<Item = u8>;
+
+//@ has it/traitalias.Alias1.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        "trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;"
+pub trait Alias1<'a, T: 'a + Clone, const N: usize> = From<[&'a T; N]>;
+
+//@ has it/traitalias.Alias2.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        'trait Alias2<T> = where T: From<String>, String: Into<T>;'
+pub trait Alias2<T> = where T: From<String>, String: Into<T>;
+
+//@ has it/traitalias.Alias3.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait Alias3 = ;'
+pub trait Alias3 =;
+
+//@ has it/traitalias.Alias4.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait Alias4 = ;'
+pub trait Alias4 = where;
+
+//@ has it/fn.usage0.html
+//@ has - '//pre[@class="rust item-decl"]' "pub fn usage0(_: impl Alias0)"
+//@ has - '//a[@href="traitalias.Alias0.html"]' 'Alias0'
+pub fn usage0(_: impl Alias0) {}
+
+// FIXME: One can only "disambiguate" intra-doc links to trait aliases with `type@` but not with
+// `trait@` (fails to resolve) or `traitalias@` (doesn't exist). We should make at least one of
+// the latter two work, right?
+
+//@ has it/link0/index.html
+//@ has - '//a/@href' 'traitalias.Alias0.html'
+//@ has - '//a/@href' 'traitalias.Alias1.html'
+/// [Alias0], [type@Alias1]
+pub mod link0 {}
+
+// Check the "extern case" (middle cleaning) //
+
+//@ aux-build: ext-trait-aliases.rs
+extern crate ext_trait_aliases as ext;
+
+//@ has it/traitalias.ExtAlias0.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias0 = Copy + Iterator<Item = u8>;'
+pub use ext::ExtAlias0;
+
+//@ has it/traitalias.ExtAlias1.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        "trait ExtAlias1<'a, T, const N: usize> = From<[&'a T; N]> where T: 'a + Clone;"
+pub use ext::ExtAlias1;
+
+//@ has it/traitalias.ExtAlias2.html
+//@ has - '//pre[@class="rust item-decl"]' \
+//        'trait ExtAlias2<T> = where T: From<String>, String: Into<T>;'
+pub use ext::ExtAlias2;
+
+//@ has it/traitalias.ExtAlias3.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias3 = Sized;'
+pub use ext::ExtAlias3;
+
+// NOTE: Middle cleaning can't discern `= Sized` and `= where Self: Sized` and that's okay.
+//@ has it/traitalias.ExtAlias4.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias4 = Sized;'
+pub use ext::ExtAlias4;
+
+//@ has it/traitalias.ExtAlias5.html
+//@ has - '//pre[@class="rust item-decl"]' 'trait ExtAlias5 = ;'
+pub use ext::ExtAlias5;
+
+//@ has it/fn.usage1.html
+//@ has - '//pre[@class="rust item-decl"]' "pub fn usage1(_: impl ExtAlias0)"
+//@ has - '//a[@href="traitalias.ExtAlias0.html"]' 'ExtAlias0'
+pub fn usage1(_: impl ExtAlias0) {}
diff --git a/tests/rustdoc/trait_alias.rs b/tests/rustdoc/trait_alias.rs
deleted file mode 100644
index bfdb9d40e2d..00000000000
--- a/tests/rustdoc/trait_alias.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![feature(trait_alias)]
-
-#![crate_name = "foo"]
-
-use std::fmt::Debug;
-
-//@ has foo/all.html '//a[@href="traitalias.CopyAlias.html"]' 'CopyAlias'
-//@ has foo/all.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
-//@ has foo/all.html '//a[@href="traitalias.Foo.html"]' 'Foo'
-
-//@ has foo/index.html '//h2[@id="trait-aliases"]' 'Trait Aliases'
-//@ has foo/index.html '//a[@class="traitalias"]' 'CopyAlias'
-//@ has foo/index.html '//a[@class="traitalias"]' 'Alias2'
-//@ has foo/index.html '//a[@class="traitalias"]' 'Foo'
-
-//@ has foo/traitalias.CopyAlias.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' 'trait CopyAlias = Copy;'
-pub trait CopyAlias = Copy;
-//@ has foo/traitalias.Alias2.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' 'trait Alias2 = Copy + Debug;'
-pub trait Alias2 = Copy + Debug;
-//@ has foo/traitalias.Foo.html
-//@ has - '//section[@id="main-content"]/pre[@class="rust item-decl"]' 'trait Foo<T> = Into<T> + Debug;'
-pub trait Foo<T> = Into<T> + Debug;
-//@ has foo/fn.bar.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
-pub fn bar<T>() where T: Alias2 {}
diff --git a/tests/ui/borrowck/move-error-snippets-ext.rs b/tests/ui/borrowck/move-error-snippets-ext.rs
index f8103228cf8..6dd68438f17 100644
--- a/tests/ui/borrowck/move-error-snippets-ext.rs
+++ b/tests/ui/borrowck/move-error-snippets-ext.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./move-error-snippets.rs`)
 
 macro_rules! aaa {
     ($c:ident) => {{
diff --git a/tests/ui/codemap_tests/two_files_data.rs b/tests/ui/codemap_tests/two_files_data.rs
index a4e4cf7e896..82852f6cfbd 100644
--- a/tests/ui/codemap_tests/two_files_data.rs
+++ b/tests/ui/codemap_tests/two_files_data.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./two_files.rs`)
 
 trait Foo { }
 
diff --git a/tests/ui/conditional-compilation/module_with_cfg.rs b/tests/ui/conditional-compilation/module_with_cfg.rs
index 29eb6d43aa7..a96f8a3e6e9 100644
--- a/tests/ui/conditional-compilation/module_with_cfg.rs
+++ b/tests/ui/conditional-compilation/module_with_cfg.rs
@@ -1,3 +1,3 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./inner-cfg-non-inline-mod.rs`)
 
 #![cfg_attr(all(), cfg(false))]
diff --git a/tests/ui/cross/cross-file-errors/underscore.rs b/tests/ui/cross/cross-file-errors/underscore.rs
index 9d075735393..73eb36cec24 100644
--- a/tests/ui/cross/cross-file-errors/underscore.rs
+++ b/tests/ui/cross/cross-file-errors/underscore.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./main.rs`)
 #![crate_type = "lib"]
 
 macro_rules! underscore {
diff --git a/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs b/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs
index 1d832a36ef5..2ccdd798c73 100644
--- a/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs
+++ b/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs
@@ -1 +1 @@
-//@ ignore-test not a test, auxiliary
+//@ ignore-auxiliary (used by `../../macro-expanded-mod.rs`)
diff --git a/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs b/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs
index 08349ba6747..9009f80c691 100644
--- a/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs
+++ b/tests/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs
@@ -1,3 +1,3 @@
-//@ ignore-test not a test, auxiliary
+//@ ignore-auxiliary (used by `../../macro-expanded-mod.rs`)
 
 mod_decl!(bar);
diff --git a/tests/ui/directory_ownership/mod_file_not_owning_aux1.rs b/tests/ui/directory_ownership/mod_file_not_owning_aux1.rs
deleted file mode 100644
index 6d6884fef04..00000000000
--- a/tests/ui/directory_ownership/mod_file_not_owning_aux1.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ ignore-test this is not a test
-
-macro_rules! m {
-    () => { mod mod_file_not_owning_aux2; }
-}
-m!();
diff --git a/tests/ui/directory_ownership/mod_file_not_owning_aux2.rs b/tests/ui/directory_ownership/mod_file_not_owning_aux2.rs
deleted file mode 100644
index 76f1c1a7276..00000000000
--- a/tests/ui/directory_ownership/mod_file_not_owning_aux2.rs
+++ /dev/null
@@ -1 +0,0 @@
-//@ ignore-test this is not a test
diff --git a/tests/ui/directory_ownership/mod_file_not_owning_aux3.rs b/tests/ui/directory_ownership/mod_file_not_owning_aux3.rs
deleted file mode 100644
index 96a5780d971..00000000000
--- a/tests/ui/directory_ownership/mod_file_not_owning_aux3.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-//@ ignore-test this is not a test
-
-mod mod_file_not_owning_aux2;
diff --git a/tests/ui/lint/expansion-time-include.rs b/tests/ui/lint/expansion-time-include.rs
index 3ecc01b045c..cbe3510f04a 100644
--- a/tests/ui/lint/expansion-time-include.rs
+++ b/tests/ui/lint/expansion-time-include.rs
@@ -1,4 +1,4 @@
-//@ ignore-test auxiliary file for expansion-time.rs
+//@ ignore-auxiliary (used by `./expansion-time.rs`)
 
 1
 2
diff --git a/tests/ui/lint/known-tool-in-submodule/submodule.rs b/tests/ui/lint/known-tool-in-submodule/submodule.rs
index 0bb2b93d53b..9c24964e94f 100644
--- a/tests/ui/lint/known-tool-in-submodule/submodule.rs
+++ b/tests/ui/lint/known-tool-in-submodule/submodule.rs
@@ -1,4 +1,4 @@
-//@ ignore-test: not a test
+//@ ignore-auxiliary (used by `./root.rs`)
 
 #[allow(tool::lint)]
 pub fn foo() {}
diff --git a/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs b/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs
index 6e16a796ff1..10e3c0f9564 100644
--- a/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs
+++ b/tests/ui/lint/lint_pre_expansion_extern_module_aux.rs
@@ -1,3 +1,3 @@
-//@ ignore-test: not a test
+//@ ignore-auxiliary (used by `./lint-pre-expansion-extern-module.rs`)
 
 pub fn try() {}
diff --git a/tests/ui/lint/unknown-lints/other.rs b/tests/ui/lint/unknown-lints/other.rs
index 25333584916..7770bc59108 100644
--- a/tests/ui/lint/unknown-lints/other.rs
+++ b/tests/ui/lint/unknown-lints/other.rs
@@ -1,6 +1,4 @@
-//@ ignore-test (auxiliary)
-
-// Companion to allow-in-other-module.rs
+//@ ignore-auxiliary (used by `./allow-in-other-module.rs`)
 
 // This should not warn.
 #![allow(not_a_real_lint)]
diff --git a/tests/ui/lint/wasm_c_abi_transition.rs b/tests/ui/lint/wasm_c_abi_transition.rs
index 1fe81679e65..411772ae890 100644
--- a/tests/ui/lint/wasm_c_abi_transition.rs
+++ b/tests/ui/lint/wasm_c_abi_transition.rs
@@ -3,7 +3,7 @@
 //@ add-core-stubs
 //@ build-fail
 
-#![feature(no_core)]
+#![feature(no_core, repr_simd)]
 #![no_core]
 #![crate_type = "lib"]
 #![deny(wasm_c_abi)]
@@ -39,3 +39,19 @@ pub fn call_other_fun(x: MyType) {
     unsafe { other_fun(x) } //~ERROR: wasm ABI transition
     //~^WARN: previously accepted
 }
+
+// Zero-sized types are safe in both ABIs
+#[repr(C)]
+pub struct MyZstType;
+#[allow(improper_ctypes_definitions)]
+pub extern "C" fn zst_safe(_x: (), _y: MyZstType) {}
+
+// The old and new wasm ABI treats simd types like `v128` the same way, so no
+// wasm_c_abi warning should be emitted.
+#[repr(simd)]
+#[allow(non_camel_case_types)]
+pub struct v128([i32; 4]);
+#[target_feature(enable = "simd128")]
+pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+//~^ WARN `extern` fn uses type `v128`, which is not FFI-safe
+//~| WARN `extern` fn uses type `v128`, which is not FFI-safe
diff --git a/tests/ui/lint/wasm_c_abi_transition.stderr b/tests/ui/lint/wasm_c_abi_transition.stderr
index 389710d5cb3..b4526bf8d68 100644
--- a/tests/ui/lint/wasm_c_abi_transition.stderr
+++ b/tests/ui/lint/wasm_c_abi_transition.stderr
@@ -1,3 +1,32 @@
+warning: `extern` fn uses type `v128`, which is not FFI-safe
+  --> $DIR/wasm_c_abi_transition.rs:55:35
+   |
+LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+   |                                   ^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: the type is defined here
+  --> $DIR/wasm_c_abi_transition.rs:53:1
+   |
+LL | pub struct v128([i32; 4]);
+   | ^^^^^^^^^^^^^^^
+   = note: `#[warn(improper_ctypes_definitions)]` on by default
+
+warning: `extern` fn uses type `v128`, which is not FFI-safe
+  --> $DIR/wasm_c_abi_transition.rs:55:44
+   |
+LL | pub extern "C" fn my_safe_simd(x: v128) -> v128 { x }
+   |                                            ^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: the type is defined here
+  --> $DIR/wasm_c_abi_transition.rs:53:1
+   |
+LL | pub struct v128([i32; 4]);
+   | ^^^^^^^^^^^^^^^
+
 error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
   --> $DIR/wasm_c_abi_transition.rs:18:1
    |
@@ -33,7 +62,7 @@ LL |     unsafe { other_fun(x) }
    = note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
    = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
 
-error: aborting due to 3 previous errors
+error: aborting due to 3 previous errors; 2 warnings emitted
 
 Future incompatibility report: Future breakage diagnostic:
 error: this function definition involves an argument of type `MyType` which is affected by the wasm ABI transition
diff --git a/tests/ui/macros/auxiliary/macro-include-items-expr.rs b/tests/ui/macros/auxiliary/macro-include-items-expr.rs
index 7394f194b80..d00491fd7e5 100644
--- a/tests/ui/macros/auxiliary/macro-include-items-expr.rs
+++ b/tests/ui/macros/auxiliary/macro-include-items-expr.rs
@@ -1,3 +1 @@
-// ignore-test: this is not a test
-
 1
diff --git a/tests/ui/macros/auxiliary/macro-include-items-item.rs b/tests/ui/macros/auxiliary/macro-include-items-item.rs
index 7d54745e03b..761cd002189 100644
--- a/tests/ui/macros/auxiliary/macro-include-items-item.rs
+++ b/tests/ui/macros/auxiliary/macro-include-items-item.rs
@@ -1,3 +1 @@
-// ignore-test: this is not a test
-
 fn foo() { bar() }
diff --git a/tests/ui/macros/include-single-expr-helper-1.rs b/tests/ui/macros/include-single-expr-helper-1.rs
index ddeeb982f64..6802719afa1 100644
--- a/tests/ui/macros/include-single-expr-helper-1.rs
+++ b/tests/ui/macros/include-single-expr-helper-1.rs
@@ -1,4 +1,4 @@
-//@ ignore-test auxiliary file for include-single-expr.rs
+//@ ignore-auxiliary (used by `./include-single-expr.rs`)
 
 0
 
diff --git a/tests/ui/macros/include-single-expr-helper.rs b/tests/ui/macros/include-single-expr-helper.rs
index e8ad9746b02..bd75bbbd583 100644
--- a/tests/ui/macros/include-single-expr-helper.rs
+++ b/tests/ui/macros/include-single-expr-helper.rs
@@ -1,4 +1,4 @@
-//@ ignore-test auxiliary file for include-single-expr.rs
+//@ ignore-auxiliary (used by `./include-single-expr.rs`)
 
 0
 10
diff --git a/tests/ui/macros/issue-69838-dir/bar.rs b/tests/ui/macros/issue-69838-dir/bar.rs
index 4433005b85f..6f91f8e2ffa 100644
--- a/tests/ui/macros/issue-69838-dir/bar.rs
+++ b/tests/ui/macros/issue-69838-dir/bar.rs
@@ -1,3 +1,3 @@
-//@ ignore-test -- this is an auxiliary file as part of another test.
+//@ ignore-auxiliary (used by `../issue-69838-mods-relative-to-included-path.rs`)
 
 pub fn i_am_in_bar() {}
diff --git a/tests/ui/macros/issue-69838-dir/included.rs b/tests/ui/macros/issue-69838-dir/included.rs
index 11fcd3eff72..328334d5e66 100644
--- a/tests/ui/macros/issue-69838-dir/included.rs
+++ b/tests/ui/macros/issue-69838-dir/included.rs
@@ -1,3 +1,3 @@
-//@ ignore-test -- this is an auxiliary file as part of another test.
+//@ ignore-auxiliary (used by `../issue-69838-mods-relative-to-included-path.rs`)
 
 pub mod bar;
diff --git a/tests/ui/macros/macro-expanded-include/foo/mod.rs b/tests/ui/macros/macro-expanded-include/foo/mod.rs
index 926d84c93e5..4e6d9e4aea4 100644
--- a/tests/ui/macros/macro-expanded-include/foo/mod.rs
+++ b/tests/ui/macros/macro-expanded-include/foo/mod.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../test.rs`)
 
 macro_rules! m {
     () => { include!("file.txt"); }
diff --git a/tests/ui/missing_non_modrs_mod/foo.rs b/tests/ui/missing_non_modrs_mod/foo.rs
index dd3e970b8c6..afdc5e39b84 100644
--- a/tests/ui/missing_non_modrs_mod/foo.rs
+++ b/tests/ui/missing_non_modrs_mod/foo.rs
@@ -1,4 +1,3 @@
-//
-//@ ignore-test this is just a helper for the real test in this dir
+//@ ignore-auxiliary (used by `./missing_non_modrs_mod.rs`)
 
 mod missing;
diff --git a/tests/ui/missing_non_modrs_mod/foo_inline.rs b/tests/ui/missing_non_modrs_mod/foo_inline.rs
index 9d46e9bdd0c..ed6d3a49101 100644
--- a/tests/ui/missing_non_modrs_mod/foo_inline.rs
+++ b/tests/ui/missing_non_modrs_mod/foo_inline.rs
@@ -1,4 +1,4 @@
-//@ ignore-test this is just a helper for the real test in this dir
+//@ ignore-auxiliary (used by `./missing_non_modrs_mod_inline.rs`)
 
 mod inline {
     mod missing;
diff --git a/tests/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr b/tests/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
index 4e48799318b..c084fbf00c2 100644
--- a/tests/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
+++ b/tests/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
@@ -1,5 +1,5 @@
 error[E0583]: file not found for module `missing`
-  --> $DIR/foo.rs:4:1
+  --> $DIR/foo.rs:3:1
    |
 LL | mod missing;
    | ^^^^^^^^^^^^
diff --git a/tests/ui/modules/mod_file_aux.rs b/tests/ui/modules/mod_file_aux.rs
index f37296b3af0..eec38d189b4 100644
--- a/tests/ui/modules/mod_file_aux.rs
+++ b/tests/ui/modules/mod_file_aux.rs
@@ -1,4 +1,3 @@
-//@ run-pass
-//@ ignore-test Not a test. Used by other tests
+//@ ignore-auxiliary (used by `./mod_file_with_path_attr.rs` and `mod_file.rs`)
 
 pub fn foo() -> isize { 10 }
diff --git a/tests/ui/modules_and_files_visibility/mod_file_aux.rs b/tests/ui/modules_and_files_visibility/mod_file_aux.rs
index 77390da75f8..6fac8dae3d7 100644
--- a/tests/ui/modules_and_files_visibility/mod_file_aux.rs
+++ b/tests/ui/modules_and_files_visibility/mod_file_aux.rs
@@ -1,3 +1,3 @@
-//@ ignore-test Not a test. Used by other tests
+//@ ignore-auxiliary (used by `./mod_file_correct_spans.rs`)
 
 pub fn foo() -> isize { 10 }
diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux.rs b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux.rs
index e00b5629c08..9a0b1c4b0d8 100644
--- a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux.rs
+++ b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux.rs
@@ -1 +1 @@
-//@ ignore-test not a test. aux file
+//@ ignore-auxiliary (used by `./mod_file_disambig.rs`)
diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs
index e00b5629c08..232c933c4cb 100644
--- a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs
+++ b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs
@@ -1 +1 @@
-//@ ignore-test not a test. aux file
+//@ ignore-auxiliary (used by `../mod_file_disambig.rs`)
diff --git a/tests/ui/non_modrs_mods/foors_mod.rs b/tests/ui/non_modrs_mods/foors_mod.rs
index b215e5f09e9..dfaa11bfe13 100644
--- a/tests/ui/non_modrs_mods/foors_mod.rs
+++ b/tests/ui/non_modrs_mods/foors_mod.rs
@@ -1,6 +1,4 @@
-//@ run-pass
-//
-//@ ignore-test: not a test, used by non_modrs_mods.rs
+//@ ignore-auxiliary (used by `./non_modrs_mods.rs`)
 
 pub mod inner_modrs_mod;
 pub mod inner_foors_mod;
diff --git a/tests/ui/non_modrs_mods_and_inline_mods/x.rs b/tests/ui/non_modrs_mods_and_inline_mods/x.rs
index c4548d39fad..38ff011d409 100644
--- a/tests/ui/non_modrs_mods_and_inline_mods/x.rs
+++ b/tests/ui/non_modrs_mods_and_inline_mods/x.rs
@@ -1,4 +1,4 @@
-//@ ignore-test: not a test
+//@ ignore-auxiliary (used by `./non_modrs_mods_and_inline_mods.rs`)
 
 pub mod y {
     pub mod z;
diff --git a/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs b/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs
index ec7b7de78d8..cac5e274fbe 100644
--- a/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs
+++ b/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs
@@ -1 +1 @@
-//@ ignore-test: not a test
+//@ ignore-auxiliary (used by `../../../non_modrs_mods_and_inline_mods.rs`)
diff --git a/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs b/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs
index 4b176ef5caa..4e578f6132f 100644
--- a/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs
+++ b/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./saturating-float-casts.rs` and `./saturating-float-casts-wasm.rs`)
 
 // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction.
 //
diff --git a/tests/ui/parser/circular_modules_hello.rs b/tests/ui/parser/circular_modules_hello.rs
index eb0284d8b41..540752ea231 100644
--- a/tests/ui/parser/circular_modules_hello.rs
+++ b/tests/ui/parser/circular_modules_hello.rs
@@ -1,4 +1,4 @@
-//@ ignore-test: this is an auxiliary file for circular-modules-main.rs
+//@ ignore-auxiliary (used by `./circular-modules-main.rs`)
 
 #[path = "circular_modules_main.rs"]
 mod circular_modules_main;
diff --git a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
index 3d758be8c05..2e9a15eb06d 100644
--- a/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
+++ b/tests/ui/parser/issues/circular-module-with-doc-comment-issue-97589/recursive.rs
@@ -1,4 +1,4 @@
-//@ ignore-test: this is an auxiliary file for circular-module-with-doc-comment-issue-97589.rs
+//@ ignore-auxiliary (used by `./circular-module-with-doc-comment-issue-97589.rs`)
 
 //! this comment caused the circular dependency checker to break
 
diff --git a/tests/ui/parser/issues/issue-48508-aux.rs b/tests/ui/parser/issues/issue-48508-aux.rs
index 0f2b4427383..0bf6490edf4 100644
--- a/tests/ui/parser/issues/issue-48508-aux.rs
+++ b/tests/ui/parser/issues/issue-48508-aux.rs
@@ -1,5 +1,4 @@
-//@ run-pass
-//@ ignore-test Not a test. Used by issue-48508.rs
+//@ ignore-auxiliary (used by `./issue-48508.rs`)
 
 pub fn other() -> f64 {
     let ยต = 1.0;
diff --git a/tests/ui/proc-macro/module.rs b/tests/ui/proc-macro/module.rs
index 210c05988bf..5878f1b7ddd 100644
--- a/tests/ui/proc-macro/module.rs
+++ b/tests/ui/proc-macro/module.rs
@@ -1 +1 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `./attributes-on-modules-fail.rs`)
diff --git a/tests/ui/proc-macro/module_with_attrs.rs b/tests/ui/proc-macro/module_with_attrs.rs
index 8a4ca92e44b..7e4ec978736 100644
--- a/tests/ui/proc-macro/module_with_attrs.rs
+++ b/tests/ui/proc-macro/module_with_attrs.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../inner-attr-non-inline-mod.rs`)
 
 #![rustfmt::skip]
 #![print_attr]
diff --git a/tests/ui/proc-macro/outer/inner.rs b/tests/ui/proc-macro/outer/inner.rs
index 210c05988bf..d0f2087321f 100644
--- a/tests/ui/proc-macro/outer/inner.rs
+++ b/tests/ui/proc-macro/outer/inner.rs
@@ -1 +1 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../attributes-on-modules-fail.rs`)
diff --git a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
index f89098f3a5e..a27176a38e2 100644
--- a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
+++ b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`)
 
 #[derive(Print)]
 enum ProceduralMasqueradeDummyType {
diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
index f89098f3a5e..a27176a38e2 100644
--- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
+++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`)
 
 #[derive(Print)]
 enum ProceduralMasqueradeDummyType {
diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs
index f89098f3a5e..765ee4be656 100644
--- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs
+++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs
@@ -1,4 +1,4 @@
-//@ ignore-test (auxiliary, used by other tests)
+//@ ignore-auxiliary (used by `../../../pretty-print-hack/hide.rs`)
 
 #[derive(Print)]
 enum ProceduralMasqueradeDummyType {
diff --git a/tests/ui/runtime/backtrace-debuginfo-aux.rs b/tests/ui/runtime/backtrace-debuginfo-aux.rs
index 24180ed2196..4493fa51f95 100644
--- a/tests/ui/runtime/backtrace-debuginfo-aux.rs
+++ b/tests/ui/runtime/backtrace-debuginfo-aux.rs
@@ -1,5 +1,4 @@
-//@ run-pass
-//@ ignore-test: not a test, used by backtrace-debuginfo.rs to test file!()
+//@ ignore-auxiliary (used by `./backtrace-debuginfo.rs` to test `file!()`)
 
 #[inline(never)]
 pub fn callback<F>(f: F) where F: FnOnce((&'static str, u32)) {
diff --git a/tests/ui/traits/next-solver/supertrait-alias-1.rs b/tests/ui/traits/next-solver/supertrait-alias-1.rs
new file mode 100644
index 00000000000..579a44677c2
--- /dev/null
+++ b/tests/ui/traits/next-solver/supertrait-alias-1.rs
@@ -0,0 +1,22 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/171>.
+// Tests that we don't try to replace `<V as Super>::Output` when replacing projections in the
+// required bounds for `dyn Trait`, b/c `V` is not relevant to the dyn type, which we were
+// previously encountering b/c we were walking into the existential projection bounds of the dyn
+// type itself.
+
+pub trait Trait: Super {}
+
+pub trait Super {
+    type Output;
+}
+
+fn bound<T: Trait + ?Sized>() {}
+
+fn visit_simd_operator<V: Super + ?Sized>() {
+    bound::<dyn Trait<Output = <V as Super>::Output>>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/supertrait-alias-2.rs b/tests/ui/traits/next-solver/supertrait-alias-2.rs
new file mode 100644
index 00000000000..a0f3e038dca
--- /dev/null
+++ b/tests/ui/traits/next-solver/supertrait-alias-2.rs
@@ -0,0 +1,25 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/171>.
+// Tests that we don't try to replace `<T as Other>::Assoc` when replacing projections in the
+// required bounds for `dyn Foo`, b/c `T` is not relevant to the dyn type, which we were
+// encountering when walking through the elaborated supertraits of `dyn Foo`.
+
+trait Other<X> {}
+
+trait Foo<T: Foo<T>>: Other<<T as Foo<T>>::Assoc> {
+    type Assoc;
+}
+
+impl<T> Foo<T> for T {
+    type Assoc = ();
+}
+
+impl<T: ?Sized> Other<()> for T {}
+
+fn is_foo<T: Foo<()> + ?Sized>() {}
+
+fn main() {
+    is_foo::<dyn Foo<(), Assoc = ()>>();
+}
diff --git a/tests/ui/traits/next-solver/supertrait-alias-3.rs b/tests/ui/traits/next-solver/supertrait-alias-3.rs
new file mode 100644
index 00000000000..78182bbc415
--- /dev/null
+++ b/tests/ui/traits/next-solver/supertrait-alias-3.rs
@@ -0,0 +1,32 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/171>.
+// Exercises a case where structural equality is insufficient when replacing projections in a dyn's
+// bounds. In this case, the bound will contain `<Self as Super<<i32 as Mirror>:Assoc>::Assoc`, but
+// the existential projections from the dyn will have `<Self as Super<i32>>::Assoc` because as an
+// optimization we eagerly normalize aliases in goals.
+
+trait Other<T> {}
+impl<T> Other<T> for T {}
+
+trait Super<T> {
+    type Assoc;
+}
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+trait Foo<A, B>: Super<<A as Mirror>::Assoc, Assoc = A> {
+    type FooAssoc: Other<<Self as Super<<A as Mirror>::Assoc>>::Assoc>;
+}
+
+fn is_foo<F: Foo<T, U> + ?Sized, T, U>() {}
+
+fn main() {
+    is_foo::<dyn Foo<i32, u32, FooAssoc = i32>, _, _>();
+}
diff --git a/tests/ui/traits/next-solver/supertrait-alias-4.rs b/tests/ui/traits/next-solver/supertrait-alias-4.rs
new file mode 100644
index 00000000000..919a768fcf2
--- /dev/null
+++ b/tests/ui/traits/next-solver/supertrait-alias-4.rs
@@ -0,0 +1,24 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Exercises the ambiguity that comes from replacing the associated types within the bounds
+// that are required for a `impl Trait for dyn Trait` built-in object impl to hold.
+
+trait Sup<T> {
+    type Assoc;
+}
+
+trait Foo<A, B>: Sup<A, Assoc = A> + Sup<B, Assoc = B> {
+    type Other: Bar<<Self as Sup<A>>::Assoc>;
+}
+
+trait Bar<T> {}
+impl Bar<i32> for () {}
+
+fn foo<A, B>(x: &(impl Foo<A, B> + ?Sized)) {}
+
+fn main() {
+    let x: &dyn Foo<_, _, Other = ()> = todo!();
+    foo(x);
+    let y: &dyn Foo<i32, u32, Other = ()> = x;
+}
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
index 736a9dfb490..be8b7fa6a93 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: --crate-type=lib
 //@ edition: 2021
-//@ rustc-env:RUST_BACKTRACE=0
 //@ check-pass
 
 // tracked in https://github.com/rust-lang/rust/issues/96572
diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
index a3b1aba7041..a42ea083d74 100644
--- a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
+++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
@@ -1,3 +1,5 @@
+//@ revisions: current next
+//@ [next] compile-flags: -Znext-solver
 //@ build-pass
 //@ edition: 2021
 
diff --git a/tests/ui/type-alias-impl-trait/tait-normalize.rs b/tests/ui/type-alias-impl-trait/tait-normalize.rs
index 38e09b6087b..a34d167bcc3 100644
--- a/tests/ui/type-alias-impl-trait/tait-normalize.rs
+++ b/tests/ui/type-alias-impl-trait/tait-normalize.rs
@@ -1,3 +1,5 @@
+//@ revisions: current next
+//@ [next] compile-flags: -Znext-solver
 //@ check-pass
 
 #![feature(type_alias_impl_trait)]