about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml17
-rw-r--r--.github/workflows/post-merge.yml7
-rw-r--r--Cargo.lock4
-rw-r--r--Cargo.toml56
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/command.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs48
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs148
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs124
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs54
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs5
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs33
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs40
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs4
-rw-r--r--compiler/rustc_lint/src/levels.rs5
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs19
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp9
-rw-r--r--compiler/rustc_middle/src/hir/map.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs117
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs5
-rw-r--r--compiler/rustc_mir_transform/src/cost_checker.rs47
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs94
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs19
-rw-r--r--compiler/rustc_resolve/src/late.rs31
-rw-r--r--compiler/rustc_session/src/config.rs7
-rw-r--r--compiler/rustc_target/src/spec/base/fuchsia.rs6
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs34
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs22
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs5
-rw-r--r--compiler/rustc_target/src/target_features.rs5
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs12
-rw-r--r--library/core/src/intrinsics/mod.rs153
-rw-r--r--library/core/src/marker.rs6
-rw-r--r--library/core/src/mem/mod.rs9
-rw-r--r--library/core/src/net/socket_addr.rs32
-rw-r--r--library/core/src/ptr/const_ptr.rs1
-rw-r--r--library/std/src/collections/hash/map.rs497
-rw-r--r--library/std/src/collections/hash/map/tests.rs93
-rw-r--r--library/std/src/os/unix/fs.rs124
-rw-r--r--library/std/src/path.rs8
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs179
-rw-r--r--library/std/src/sys/pal/unix/os.rs7
-rw-r--r--library/std/src/sys/pal/unix/process/process_common.rs2
-rw-r--r--library/std/src/sys/path/unix.rs5
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs38
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs10
-rw-r--r--src/bootstrap/src/core/build_steps/suggest.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs4
-rw-r--r--src/bootstrap/src/core/builder/mod.rs1
-rw-r--r--src/bootstrap/src/core/config/mod.rs2
-rw-r--r--src/bootstrap/src/core/download.rs2
-rw-r--r--src/bootstrap/src/lib.rs13
-rw-r--r--src/bootstrap/src/utils/exec.rs5
-rw-r--r--src/bootstrap/src/utils/metrics.rs5
-rw-r--r--src/ci/citool/src/jobs.rs5
-rw-r--r--src/ci/citool/src/merge_report.rs215
-rw-r--r--src/ci/citool/tests/jobs.rs2
-rw-r--r--src/ci/citool/tests/test-jobs.yml1
-rw-r--r--src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile4
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile1
-rwxr-xr-xsrc/ci/docker/run.sh1
-rw-r--r--src/ci/github-actions/jobs.yml2
-rwxr-xr-xsrc/ci/run.sh30
-rw-r--r--src/doc/rustc-dev-guide/README.md13
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/updating-llvm.md23
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md4
-rw-r--r--src/doc/rustc-dev-guide/src/building/new-target.md5
-rw-r--r--src/doc/rustc-dev-guide/src/effects.md225
-rw-r--r--src/doc/rustc-dev-guide/src/solve/trait-solving.md3
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md6
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md24
-rw-r--r--src/etc/rust_analyzer_eglot.el1
-rw-r--r--src/etc/rust_analyzer_helix.toml1
-rw-r--r--src/etc/rust_analyzer_settings.json1
-rw-r--r--src/etc/rust_analyzer_zed.json1
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs3
-rw-r--r--src/tools/miri/src/machine.rs107
-rw-r--r--src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr4
-rw-r--r--src/tools/opt-dist/src/tests.rs81
-rw-r--r--src/tools/rustbook/Cargo.lock12
-rw-r--r--src/tools/rustbook/Cargo.toml2
-rw-r--r--src/tools/rustbook/src/main.rs1
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/x/Cargo.lock7
-rw-r--r--tests/codegen/enum/enum-two-variants-match.rs37
-rw-r--r--tests/codegen/intrinsics/cold_path2.rs4
-rw-r--r--tests/codegen/match-optimizes-away.rs11
-rw-r--r--tests/codegen/range-loop.rs44
-rw-r--r--tests/codegen/try_question_mark_nop.rs6
-rw-r--r--tests/crashes/125059.rs12
-rw-r--r--tests/mir-opt/inline/exponential_runtime.rs5
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff5
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff5
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff125
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff162
-rw-r--r--tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir24
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir20
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir26
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir21
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir21
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir24
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir30
-rw-r--r--tests/pretty/hir-fn-params.pp38
-rw-r--r--tests/pretty/hir-fn-params.rs34
-rw-r--r--tests/ui/abi/compatibility.rs1
-rw-r--r--tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr12
-rw-r--r--tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr20
-rw-r--r--tests/ui/asm/loongarch/bad-reg.rs1
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr4
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/display.stderr8
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/rendering.fixed15
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/rendering.rs14
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/rendering.stderr12
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-wrap.rs1
-rw-r--r--tests/ui/check-cfg/target_feature.stderr5
-rw-r--r--tests/ui/crate_type_flag.rs4
-rw-r--r--tests/ui/crate_type_flag.stderr2
-rw-r--r--tests/ui/delegation/foreign-fn.rs22
-rw-r--r--tests/ui/delegation/foreign-fn.stderr27
-rw-r--r--tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/crate-type-flag.rs6
-rw-r--r--tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr2
-rw-r--r--tests/ui/lint/unused/unused-field-in-pat-field.rs21
-rw-r--r--tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr3
-rw-r--r--tests/ui/parser/shebang/shebang-must-start-file.stderr3
-rw-r--r--tests/ui/parser/shebang/shebang-split.rs5
-rw-r--r--tests/ui/parser/shebang/shebang-split.stderr8
-rw-r--r--tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.rs12
-rw-r--r--tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.stderr10
-rw-r--r--tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs15
-rw-r--r--tests/ui/stability-attribute/check-stability-issue-138319.rs39
-rw-r--r--tests/ui/stability-attribute/check-stability-issue-138319.stderr10
-rw-r--r--tests/ui/typeck/cyclic_type_ice.stderr2
-rw-r--r--triagebot.toml2
157 files changed, 2382 insertions, 1636 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f166e0c0b41..96c0955e871 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -68,6 +68,7 @@ jobs:
     timeout-minutes: 360
     env:
       CI_JOB_NAME: ${{ matrix.name }}
+      CI_JOB_DOC_URL: ${{ matrix.doc_url }}
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
       HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
@@ -190,8 +191,20 @@ jobs:
           CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=../../../build/citool cargo build
 
       - name: run the build
-        # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
-        run: src/ci/scripts/run-build-from-ci.sh 2>&1
+        run: |
+          set +e
+          # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
+          src/ci/scripts/run-build-from-ci.sh 2>&1
+          STATUS=$?
+          set -e
+
+          if [[ "$STATUS" -ne 0 && -n "$CI_JOB_DOC_URL" ]]; then
+            echo "****************************************************************************"
+            echo "To find more information about this job, visit the following URL:"
+            echo "$CI_JOB_DOC_URL"
+            echo "****************************************************************************"
+          fi
+          exit ${STATUS}
         env:
           AWS_ACCESS_KEY_ID: ${{ env.CACHES_AWS_ACCESS_KEY_ID }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index 31e075f45d6..de31c28cc90 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -35,8 +35,13 @@ jobs:
 
           cd src/ci/citool
 
-          echo "Post-merge analysis result" > output.log
+          printf "*This is an experimental post-merge analysis report. You can ignore it.*\n\n" > output.log
+          printf "<details>\n<summary>Post-merge report</summary>\n\n" >> output.log
+
           cargo run --release post-merge-report ${PARENT_COMMIT} ${{ github.sha }} >> output.log
+
+          printf "</details>\n" >> output.log
+
           cat output.log
 
           gh pr comment ${HEAD_PR} -F output.log
diff --git a/Cargo.lock b/Cargo.lock
index 942f8f43935..6d252ca8c82 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6439,6 +6439,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
 
 [[package]]
+name = "x"
+version = "0.1.1"
+
+[[package]]
 name = "xattr"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 915ec2e00ca..16ff0f61593 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,50 +1,53 @@
 [workspace]
 resolver = "2"
 members = [
+# tidy-alphabetical-start
   "compiler/rustc",
   "src/build_helper",
   "src/etc/test-float-parse",
-  "src/rustc-std-workspace/rustc-std-workspace-core",
   "src/rustc-std-workspace/rustc-std-workspace-alloc",
+  "src/rustc-std-workspace/rustc-std-workspace-core",
   "src/rustc-std-workspace/rustc-std-workspace-std",
   "src/rustdoc-json-types",
+  "src/tools/build-manifest",
+  "src/tools/bump-stage0",
   "src/tools/cargotest",
   "src/tools/clippy",
   "src/tools/clippy/clippy_dev",
+  "src/tools/collect-license-metadata",
   "src/tools/compiletest",
-  "src/tools/run-make-support",
+  "src/tools/coverage-dump",
+  "src/tools/features-status-dump",
+  "src/tools/generate-copyright",
+  "src/tools/generate-windows-sys",
+  "src/tools/html-checker",
+  "src/tools/jsondocck",
+  "src/tools/jsondoclint",
   "src/tools/linkchecker",
   "src/tools/lint-docs",
+  "src/tools/lld-wrapper",
+  "src/tools/llvm-bitcode-linker",
+  "src/tools/miri",
+  "src/tools/miri/cargo-miri",
   "src/tools/miropt-test-tools",
-  "src/tools/unstable-book-gen",
-  "src/tools/tidy",
-  "src/tools/tier-check",
-  "src/tools/build-manifest",
+  "src/tools/opt-dist",
   "src/tools/remote-test-client",
   "src/tools/remote-test-server",
+  "src/tools/replace-version-placeholder",
+  "src/tools/run-make-support",
   "src/tools/rust-installer",
   "src/tools/rustdoc",
-  "src/tools/rustfmt",
-  "src/tools/miri",
-  "src/tools/miri/cargo-miri",
+  "src/tools/rustdoc-gui-test",
   "src/tools/rustdoc-themes",
-  "src/tools/unicode-table-generator",
-  "src/tools/jsondocck",
-  "src/tools/jsondoclint",
-  "src/tools/llvm-bitcode-linker",
-  "src/tools/html-checker",
-  "src/tools/bump-stage0",
-  "src/tools/replace-version-placeholder",
-  "src/tools/lld-wrapper",
-  "src/tools/collect-license-metadata",
-  "src/tools/generate-copyright",
+  "src/tools/rustfmt",
   "src/tools/suggest-tests",
-  "src/tools/generate-windows-sys",
-  "src/tools/rustdoc-gui-test",
-  "src/tools/opt-dist",
-  "src/tools/coverage-dump",
+  "src/tools/tidy",
+  "src/tools/tier-check",
+  "src/tools/unicode-table-generator",
+  "src/tools/unstable-book-gen",
   "src/tools/wasm-component-ld",
-  "src/tools/features-status-dump",
+  "src/tools/x",
+# tidy-alphabetical-end
 ]
 
 exclude = [
@@ -55,11 +58,6 @@ exclude = [
   "tests/rustdoc-gui",
   # HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
   "obj",
-  # The `x` binary is a thin wrapper that calls `x.py`, which initializes
-  # submodules, before which workspace members cannot be invoked because
-  # not all `Cargo.toml` files are available, so we exclude the `x` binary,
-  # so it can be invoked before the current checkout is set up.
-  "src/tools/x",
 ]
 
 [profile.release.package.rustc-rayon-core]
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 946f2cafa15..efc1fa05c5f 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -190,14 +190,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
     ) -> hir::FnSig<'hir> {
         let header = if let Some(local_sig_id) = sig_id.as_local() {
             match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
-                Some(sig) => self.lower_fn_header(
-                    sig.header,
+                Some(sig) => {
+                    let parent = self.tcx.parent(sig_id);
                     // HACK: we override the default safety instead of generating attributes from the ether.
                     // We are not forwarding the attributes, as the delegation fn sigs are collected on the ast,
                     // and here we need the hir attributes.
-                    if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe },
-                    &[],
-                ),
+                    let default_safety =
+                        if sig.target_feature || self.tcx.def_kind(parent) == DefKind::ForeignMod {
+                            hir::Safety::Unsafe
+                        } else {
+                            hir::Safety::Safe
+                        };
+                    self.lower_fn_header(sig.header, default_safety, &[])
+                }
                 None => self.generate_header_error(),
             }
         } else {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c7d37e2704d..df671cf4b86 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1516,7 +1516,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
         self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
             PatKind::Ident(_, ident, _) => self.lower_ident(ident),
-            _ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
+            PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
+            _ => {
+                self.dcx().span_delayed_bug(
+                    param.pat.span,
+                    "non-ident/wild param pat must trigger an error",
+                );
+                Ident::new(kw::Empty, self.lower_span(param.pat.span))
+            }
         }))
     }
 
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 6735ae024d1..75f3a3c1972 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -1031,7 +1031,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Int(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1052,7 +1052,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Uint(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1073,7 +1073,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Int(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
@@ -1094,7 +1094,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
             let layout = src.layout();
             match layout.ty.kind() {
-                ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
+                ty::Uint(_) => {}
                 _ => {
                     report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return Ok(());
diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs
index 63023fdba20..383d0579e52 100644
--- a/compiler/rustc_codegen_ssa/src/back/command.rs
+++ b/compiler/rustc_codegen_ssa/src/back/command.rs
@@ -143,13 +143,6 @@ impl Command {
             return false;
         }
 
-        // Right now LLD doesn't support the `@` syntax of passing an argument
-        // through files, so regardless of the platform we try to go to the OS
-        // on this one.
-        if let Program::Lld(..) = self.program {
-            return false;
-        }
-
         // Ok so on Windows to spawn a process is 32,768 characters in its
         // command line [1]. Unfortunately we don't actually have access to that
         // as it's calculated just before spawning. Instead we perform a
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 23baab3124e..99f35b79208 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -205,7 +205,12 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
             | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
 
             PlaceContext::NonMutatingUse(
-                NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
+                NonMutatingUseContext::Copy
+                | NonMutatingUseContext::Move
+                // Inspect covers things like `PtrMetadata` and `Discriminant`
+                // which we can treat similar to `Copy` use for the purpose of
+                // whether we can use SSA variables for things.
+                | NonMutatingUseContext::Inspect,
             ) => match &mut self.locals[local] {
                 LocalKind::ZST => {}
                 LocalKind::Memory => {}
@@ -229,8 +234,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer
                 | MutatingUseContext::Projection,
             )
             | PlaceContext::NonMutatingUse(
-                NonMutatingUseContext::Inspect
-                | NonMutatingUseContext::SharedBorrow
+                NonMutatingUseContext::SharedBorrow
                 | NonMutatingUseContext::FakeBorrow
                 | NonMutatingUseContext::RawBorrow
                 | NonMutatingUseContext::Projection,
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index b34e966ba6c..63025a4574f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -62,7 +62,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let callee_ty = instance.ty(bx.tcx(), bx.typing_env());
 
         let ty::FnDef(def_id, fn_args) = *callee_ty.kind() else {
-            bug!("expected fn item type, found {}", callee_ty);
+            span_bug!(span, "expected fn item type, found {}", callee_ty);
         };
 
         let sig = callee_ty.fn_sig(bx.tcx());
@@ -325,14 +325,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
-            sym::discriminant_value => {
-                if ret_ty.is_integral() {
-                    args[0].deref(bx.cx()).codegen_get_discr(bx, ret_ty)
-                } else {
-                    span_bug!(span, "Invalid discriminant type for `{:?}`", arg_tys[0])
-                }
-            }
-
             // This requires that atomic intrinsics follow a specific naming pattern:
             // "atomic_<operation>[_<ordering>]"
             name if let Some(atomic) = name_str.strip_prefix("atomic_") => {
@@ -441,6 +433,40 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
 
                     // These are all AtomicRMW ops
+                    "max" | "min" => {
+                        let atom_op = if instruction == "max" {
+                            AtomicRmwBinOp::AtomicMax
+                        } else {
+                            AtomicRmwBinOp::AtomicMin
+                        };
+
+                        let ty = fn_args.type_at(0);
+                        if matches!(ty.kind(), ty::Int(_)) {
+                            let ptr = args[0].immediate();
+                            let val = args[1].immediate();
+                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
+                        } else {
+                            invalid_monomorphization(ty);
+                            return Ok(());
+                        }
+                    }
+                    "umax" | "umin" => {
+                        let atom_op = if instruction == "umax" {
+                            AtomicRmwBinOp::AtomicUMax
+                        } else {
+                            AtomicRmwBinOp::AtomicUMin
+                        };
+
+                        let ty = fn_args.type_at(0);
+                        if matches!(ty.kind(), ty::Uint(_)) {
+                            let ptr = args[0].immediate();
+                            let val = args[1].immediate();
+                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
+                        } else {
+                            invalid_monomorphization(ty);
+                            return Ok(());
+                        }
+                    }
                     op => {
                         let atom_op = match op {
                             "xchg" => AtomicRmwBinOp::AtomicXchg,
@@ -450,10 +476,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             "nand" => AtomicRmwBinOp::AtomicNand,
                             "or" => AtomicRmwBinOp::AtomicOr,
                             "xor" => AtomicRmwBinOp::AtomicXor,
-                            "max" => AtomicRmwBinOp::AtomicMax,
-                            "min" => AtomicRmwBinOp::AtomicMin,
-                            "umax" => AtomicRmwBinOp::AtomicUMax,
-                            "umin" => AtomicRmwBinOp::AtomicUMin,
                             _ => bx.sess().dcx().emit_fatal(errors::UnknownAtomicOperation),
                         };
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index acae09b2c25..7e355b6406a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -3,16 +3,17 @@ use std::fmt;
 use arrayvec::ArrayVec;
 use either::Either;
 use rustc_abi as abi;
-use rustc_abi::{Align, BackendRepr, Size};
+use rustc_abi::{Align, BackendRepr, FIRST_VARIANT, Primitive, Size, TagEncoding, Variants};
 use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range};
 use rustc_middle::mir::{self, ConstValue};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::{bug, span_bug};
-use tracing::debug;
+use tracing::{debug, instrument};
 
 use super::place::{PlaceRef, PlaceValue};
 use super::{FunctionCx, LocalRef};
+use crate::common::IntPredicate;
 use crate::traits::*;
 use crate::{MemFlags, size_of_val};
 
@@ -415,6 +416,149 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
 
         OperandRef { val, layout: field }
     }
+
+    /// Obtain the actual discriminant of a value.
+    #[instrument(level = "trace", skip(fx, bx))]
+    pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+        self,
+        fx: &mut FunctionCx<'a, 'tcx, Bx>,
+        bx: &mut Bx,
+        cast_to: Ty<'tcx>,
+    ) -> V {
+        let dl = &bx.tcx().data_layout;
+        let cast_to_layout = bx.cx().layout_of(cast_to);
+        let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
+
+        // We check uninhabitedness separately because a type like
+        // `enum Foo { Bar(i32, !) }` is still reported as `Variants::Single`,
+        // *not* as `Variants::Empty`.
+        if self.layout.is_uninhabited() {
+            return bx.cx().const_poison(cast_to);
+        }
+
+        let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
+            Variants::Empty => unreachable!("we already handled uninhabited types"),
+            Variants::Single { index } => {
+                let discr_val =
+                    if let Some(discr) = self.layout.ty.discriminant_for_variant(bx.tcx(), index) {
+                        discr.val
+                    } else {
+                        // This arm is for types which are neither enums nor coroutines,
+                        // and thus for which the only possible "variant" should be the first one.
+                        assert_eq!(index, FIRST_VARIANT);
+                        // There's thus no actual discriminant to return, so we return
+                        // what it would have been if this was a single-variant enum.
+                        0
+                    };
+                return bx.cx().const_uint_big(cast_to, discr_val);
+            }
+            Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
+                (tag, tag_encoding, tag_field)
+            }
+        };
+
+        // Read the tag/niche-encoded discriminant from memory.
+        let tag_op = match self.val {
+            OperandValue::ZeroSized => bug!(),
+            OperandValue::Immediate(_) | OperandValue::Pair(_, _) => {
+                self.extract_field(fx, bx, tag_field)
+            }
+            OperandValue::Ref(place) => {
+                let tag = place.with_type(self.layout).project_field(bx, tag_field);
+                bx.load_operand(tag)
+            }
+        };
+        let tag_imm = tag_op.immediate();
+
+        // Decode the discriminant (specifically if it's niche-encoded).
+        match *tag_encoding {
+            TagEncoding::Direct => {
+                let signed = match tag_scalar.primitive() {
+                    // We use `i1` for bytes that are always `0` or `1`,
+                    // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
+                    // let LLVM interpret the `i1` as signed, because
+                    // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`.
+                    Primitive::Int(_, signed) => !tag_scalar.is_bool() && signed,
+                    _ => false,
+                };
+                bx.intcast(tag_imm, cast_to, signed)
+            }
+            TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
+                // Cast to an integer so we don't have to treat a pointer as a
+                // special case.
+                let (tag, tag_llty) = match tag_scalar.primitive() {
+                    // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+                    Primitive::Pointer(_) => {
+                        let t = bx.type_from_integer(dl.ptr_sized_integer());
+                        let tag = bx.ptrtoint(tag_imm, t);
+                        (tag, t)
+                    }
+                    _ => (tag_imm, bx.cx().immediate_backend_type(tag_op.layout)),
+                };
+
+                let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
+
+                // We have a subrange `niche_start..=niche_end` inside `range`.
+                // If the value of the tag is inside this subrange, it's a
+                // "niche value", an increment of the discriminant. Otherwise it
+                // indicates the untagged variant.
+                // A general algorithm to extract the discriminant from the tag
+                // is:
+                // relative_tag = tag - niche_start
+                // is_niche = relative_tag <= (ule) relative_max
+                // discr = if is_niche {
+                //     cast(relative_tag) + niche_variants.start()
+                // } else {
+                //     untagged_variant
+                // }
+                // However, we will likely be able to emit simpler code.
+                let (is_niche, tagged_discr, delta) = if relative_max == 0 {
+                    // Best case scenario: only one tagged variant. This will
+                    // likely become just a comparison and a jump.
+                    // The algorithm is:
+                    // is_niche = tag == niche_start
+                    // discr = if is_niche {
+                    //     niche_start
+                    // } else {
+                    //     untagged_variant
+                    // }
+                    let niche_start = bx.cx().const_uint_big(tag_llty, niche_start);
+                    let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start);
+                    let tagged_discr =
+                        bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
+                    (is_niche, tagged_discr, 0)
+                } else {
+                    // The special cases don't apply, so we'll have to go with
+                    // the general algorithm.
+                    let relative_discr = bx.sub(tag, bx.cx().const_uint_big(tag_llty, niche_start));
+                    let cast_tag = bx.intcast(relative_discr, cast_to, false);
+                    let is_niche = bx.icmp(
+                        IntPredicate::IntULE,
+                        relative_discr,
+                        bx.cx().const_uint(tag_llty, relative_max as u64),
+                    );
+                    (is_niche, cast_tag, niche_variants.start().as_u32() as u128)
+                };
+
+                let tagged_discr = if delta == 0 {
+                    tagged_discr
+                } else {
+                    bx.add(tagged_discr, bx.cx().const_uint_big(cast_to, delta))
+                };
+
+                let discr = bx.select(
+                    is_niche,
+                    tagged_discr,
+                    bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
+                );
+
+                // In principle we could insert assumes on the possible range of `discr`, but
+                // currently in LLVM this seems to be a pessimization.
+
+                discr
+            }
+        }
+    }
 }
 
 impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 6988724b421..31db7fa9a18 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -1,4 +1,3 @@
-use rustc_abi::Primitive::{Int, Pointer};
 use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants};
 use rustc_middle::mir::PlaceTy;
 use rustc_middle::mir::interpret::Scalar;
@@ -233,129 +232,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         val.with_type(field)
     }
 
-    /// Obtain the actual discriminant of a value.
-    #[instrument(level = "trace", skip(bx))]
-    pub fn codegen_get_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
-        self,
-        bx: &mut Bx,
-        cast_to: Ty<'tcx>,
-    ) -> V {
-        let dl = &bx.tcx().data_layout;
-        let cast_to_layout = bx.cx().layout_of(cast_to);
-        let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
-        if self.layout.is_uninhabited() {
-            return bx.cx().const_poison(cast_to);
-        }
-        let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
-            Variants::Empty => unreachable!("we already handled uninhabited types"),
-            Variants::Single { index } => {
-                let discr_val = self
-                    .layout
-                    .ty
-                    .discriminant_for_variant(bx.cx().tcx(), index)
-                    .map_or(index.as_u32() as u128, |discr| discr.val);
-                return bx.cx().const_uint_big(cast_to, discr_val);
-            }
-            Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
-                (tag, tag_encoding, tag_field)
-            }
-        };
-
-        // Read the tag/niche-encoded discriminant from memory.
-        let tag = self.project_field(bx, tag_field);
-        let tag_op = bx.load_operand(tag);
-        let tag_imm = tag_op.immediate();
-
-        // Decode the discriminant (specifically if it's niche-encoded).
-        match *tag_encoding {
-            TagEncoding::Direct => {
-                let signed = match tag_scalar.primitive() {
-                    // We use `i1` for bytes that are always `0` or `1`,
-                    // e.g., `#[repr(i8)] enum E { A, B }`, but we can't
-                    // let LLVM interpret the `i1` as signed, because
-                    // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`.
-                    Int(_, signed) => !tag_scalar.is_bool() && signed,
-                    _ => false,
-                };
-                bx.intcast(tag_imm, cast_to, signed)
-            }
-            TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
-                // Cast to an integer so we don't have to treat a pointer as a
-                // special case.
-                let (tag, tag_llty) = match tag_scalar.primitive() {
-                    // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
-                    Pointer(_) => {
-                        let t = bx.type_from_integer(dl.ptr_sized_integer());
-                        let tag = bx.ptrtoint(tag_imm, t);
-                        (tag, t)
-                    }
-                    _ => (tag_imm, bx.cx().immediate_backend_type(tag_op.layout)),
-                };
-
-                let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
-
-                // We have a subrange `niche_start..=niche_end` inside `range`.
-                // If the value of the tag is inside this subrange, it's a
-                // "niche value", an increment of the discriminant. Otherwise it
-                // indicates the untagged variant.
-                // A general algorithm to extract the discriminant from the tag
-                // is:
-                // relative_tag = tag - niche_start
-                // is_niche = relative_tag <= (ule) relative_max
-                // discr = if is_niche {
-                //     cast(relative_tag) + niche_variants.start()
-                // } else {
-                //     untagged_variant
-                // }
-                // However, we will likely be able to emit simpler code.
-                let (is_niche, tagged_discr, delta) = if relative_max == 0 {
-                    // Best case scenario: only one tagged variant. This will
-                    // likely become just a comparison and a jump.
-                    // The algorithm is:
-                    // is_niche = tag == niche_start
-                    // discr = if is_niche {
-                    //     niche_start
-                    // } else {
-                    //     untagged_variant
-                    // }
-                    let niche_start = bx.cx().const_uint_big(tag_llty, niche_start);
-                    let is_niche = bx.icmp(IntPredicate::IntEQ, tag, niche_start);
-                    let tagged_discr =
-                        bx.cx().const_uint(cast_to, niche_variants.start().as_u32() as u64);
-                    (is_niche, tagged_discr, 0)
-                } else {
-                    // The special cases don't apply, so we'll have to go with
-                    // the general algorithm.
-                    let relative_discr = bx.sub(tag, bx.cx().const_uint_big(tag_llty, niche_start));
-                    let cast_tag = bx.intcast(relative_discr, cast_to, false);
-                    let is_niche = bx.icmp(
-                        IntPredicate::IntULE,
-                        relative_discr,
-                        bx.cx().const_uint(tag_llty, relative_max as u64),
-                    );
-                    (is_niche, cast_tag, niche_variants.start().as_u32() as u128)
-                };
-
-                let tagged_discr = if delta == 0 {
-                    tagged_discr
-                } else {
-                    bx.add(tagged_discr, bx.cx().const_uint_big(cast_to, delta))
-                };
-
-                let discr = bx.select(
-                    is_niche,
-                    tagged_discr,
-                    bx.cx().const_uint(cast_to, untagged_variant.as_u32() as u64),
-                );
-
-                // In principle we could insert assumes on the possible range of `discr`, but
-                // currently in LLVM this seems to be a pessimization.
-
-                discr
-            }
-        }
-    }
-
     /// Sets the discriminant for a new value of the given case of the given
     /// representation.
     pub fn codegen_set_discr<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 95b108b1d33..96be44ee09f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -706,7 +706,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Discriminant(ref place) => {
                 let discr_ty = rvalue.ty(self.mir, bx.tcx());
                 let discr_ty = self.monomorphize(discr_ty);
-                let discr = self.codegen_place(bx, place.as_ref()).codegen_get_discr(bx, discr_ty);
+                let operand = self.codegen_consume(bx, place.as_ref());
+                let discr = operand.codegen_get_discr(self, bx, discr_ty);
                 OperandRef {
                     val: OperandValue::Immediate(discr),
                     layout: self.cx.layout_of(discr_ty),
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 1a799f5dea5..a21bf018d01 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -8,7 +8,6 @@ use std::hash::Hash;
 
 use rustc_abi::{Align, Size};
 use rustc_apfloat::{Float, FloatConvert};
-use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::TyAndLayout;
@@ -21,7 +20,6 @@ use super::{
     AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation,
     CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind,
     Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup,
-    throw_unsup_format,
 };
 
 /// Data returned by [`Machine::after_stack_pop`], and consumed by
@@ -361,6 +359,19 @@ pub trait Machine<'tcx>: Sized {
         size: i64,
     ) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
 
+    /// Return a "root" pointer for the given allocation: the one that is used for direct
+    /// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
+    ///
+    /// Not called on `extern` or thread-local statics (those use the methods above).
+    ///
+    /// `kind` is the kind of the allocation the pointer points to; it can be `None` when
+    /// it's a global and `GLOBAL_KIND` is `None`.
+    fn adjust_alloc_root_pointer(
+        ecx: &InterpCx<'tcx, Self>,
+        ptr: Pointer,
+        kind: Option<MemoryKind<Self::MemoryKind>>,
+    ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
+
     /// Called to adjust global allocations to the Provenance and AllocExtra of this machine.
     ///
     /// If `alloc` contains pointers, then they are all pointing to globals.
@@ -375,11 +386,12 @@ pub trait Machine<'tcx>: Sized {
         alloc: &'b Allocation,
     ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
 
-    /// Initialize the extra state of an allocation.
+    /// Initialize the extra state of an allocation local to this machine.
     ///
-    /// This is guaranteed to be called exactly once on all allocations that are accessed by the
-    /// program.
-    fn init_alloc_extra(
+    /// This is guaranteed to be called exactly once on all allocations local to this machine.
+    /// It will not be called automatically for global allocations; `adjust_global_allocation`
+    /// has to do that itself if that is desired.
+    fn init_local_allocation(
         ecx: &InterpCx<'tcx, Self>,
         id: AllocId,
         kind: MemoryKind<Self::MemoryKind>,
@@ -387,34 +399,6 @@ pub trait Machine<'tcx>: Sized {
         align: Align,
     ) -> InterpResult<'tcx, Self::AllocExtra>;
 
-    /// Return a "root" pointer for the given allocation: the one that is used for direct
-    /// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
-    ///
-    /// Not called on `extern` or thread-local statics (those use the methods above).
-    ///
-    /// `kind` is the kind of the allocation the pointer points to; it can be `None` when
-    /// it's a global and `GLOBAL_KIND` is `None`.
-    fn adjust_alloc_root_pointer(
-        ecx: &InterpCx<'tcx, Self>,
-        ptr: Pointer,
-        kind: Option<MemoryKind<Self::MemoryKind>>,
-    ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
-
-    /// Evaluate the inline assembly.
-    ///
-    /// This should take care of jumping to the next block (one of `targets`) when asm goto
-    /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
-    /// naked_asm! or `InlineAsmOptions::NORETURN` being set.
-    fn eval_inline_asm(
-        _ecx: &mut InterpCx<'tcx, Self>,
-        _template: &'tcx [InlineAsmTemplatePiece],
-        _operands: &[mir::InlineAsmOperand<'tcx>],
-        _options: InlineAsmOptions,
-        _targets: &[mir::BasicBlock],
-    ) -> InterpResult<'tcx> {
-        throw_unsup_format!("inline assembly is not supported")
-    }
-
     /// Hook for performing extra checks on a memory read access.
     ///
     /// This will *not* be called during validation!
@@ -699,7 +683,7 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
         interp_ok(Cow::Borrowed(alloc))
     }
 
-    fn init_alloc_extra(
+    fn init_local_allocation(
         _ecx: &InterpCx<$tcx, Self>,
         _id: AllocId,
         _kind: MemoryKind<Self::MemoryKind>,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index e5af0673629..75726269a86 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -263,9 +263,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             M::GLOBAL_KIND.map(MemoryKind::Machine),
             "dynamically allocating global memory"
         );
-        // We have set things up so we don't need to call `adjust_from_tcx` here,
-        // so we avoid copying the entire allocation contents.
-        let extra = M::init_alloc_extra(self, id, kind, alloc.size(), alloc.align)?;
+        // This cannot be merged with the `adjust_global_allocation` code path
+        // since here we have an allocation that already uses `M::Bytes`.
+        let extra = M::init_local_allocation(self, id, kind, alloc.size(), alloc.align)?;
         let alloc = alloc.with_extra(extra);
         self.memory.alloc_map.insert(id, (kind, alloc));
         M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 6a17da61c8b..ddf2d65914f 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -14,7 +14,7 @@ use tracing::{info, instrument, trace};
 
 use super::{
     FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
-    Projectable, Scalar, interp_ok, throw_ub,
+    Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format,
 };
 use crate::util;
 
@@ -590,8 +590,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 terminator.kind
             ),
 
-            InlineAsm { template, ref operands, options, ref targets, .. } => {
-                M::eval_inline_asm(self, template, operands, options, targets)?;
+            InlineAsm { .. } => {
+                throw_unsup_format!("inline assembly is not supported");
             }
         }
 
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 9c28fac809d..b4a16b2b805 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -84,6 +84,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt as _};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::print::with_types_for_signature;
 use rustc_middle::ty::{self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypingMode};
 use rustc_middle::{bug, span_bug};
 use rustc_session::parse::feature_err;
@@ -240,11 +241,11 @@ fn missing_items_err(
         (Vec::new(), Vec::new(), Vec::new());
 
     for &trait_item in missing_items {
-        let snippet = suggestion_signature(
+        let snippet = with_types_for_signature!(suggestion_signature(
             tcx,
             trait_item,
             tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(),
-        );
+        ));
         let code = format!("{padding}{snippet}\n{padding}");
         if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
             missing_trait_item_label
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 3067766fb4d..1409310339a 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2148,9 +2148,11 @@ impl<'a> State<'a> {
                 s.print_implicit_self(&decl.implicit_self);
             } else {
                 if let Some(arg_name) = arg_names.get(i) {
-                    s.word(arg_name.to_string());
-                    s.word(":");
-                    s.space();
+                    if arg_name.name != kw::Empty {
+                        s.word(arg_name.to_string());
+                        s.word(":");
+                        s.space();
+                    }
                 } else if let Some(body_id) = body_id {
                     s.ann.nested(s, Nested::BodyParamPat(body_id, i));
                     s.word(":");
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 70b49fea34f..5270c8ed356 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -32,6 +32,7 @@ use rustc_ast::util::parser::ExprPrecedence;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
+use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, ExprKind};
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_macros::{TypeFoldable, TypeVisitable};
@@ -155,7 +156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Debug)]
 enum CastError<'tcx> {
     ErrorGuaranteed(ErrorGuaranteed),
 
@@ -182,6 +183,7 @@ enum CastError<'tcx> {
     /// when we're typechecking a type parameter with a ?Sized bound.
     IntToWideCast(Option<&'static str>),
     ForeignNonExhaustiveAdt,
+    PtrPtrAddingAutoTrait(Vec<DefId>),
 }
 
 impl From<ErrorGuaranteed> for CastError<'_> {
@@ -596,6 +598,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 .with_note("cannot cast an enum with a non-exhaustive variant when it's defined in another crate")
                 .emit();
             }
+            CastError::PtrPtrAddingAutoTrait(added) => {
+                fcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
+                    span: self.span,
+                    traits_len: added.len(),
+                    traits: {
+                        let mut traits: Vec<_> = added
+                            .into_iter()
+                            .map(|trait_did| fcx.tcx.def_path_str(trait_did))
+                            .collect();
+
+                        traits.sort();
+                        traits.into()
+                    },
+                });
+            }
         }
     }
 
@@ -940,19 +957,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             .collect::<Vec<_>>();
 
                         if !added.is_empty() {
-                            tcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
-                                span: self.span,
-                                traits_len: added.len(),
-                                traits: {
-                                    let mut traits: Vec<_> = added
-                                        .into_iter()
-                                        .map(|trait_did| tcx.def_path_str(trait_did))
-                                        .collect();
-
-                                    traits.sort();
-                                    traits.into()
-                                },
-                            });
+                            return Err(CastError::PtrPtrAddingAutoTrait(added));
                         }
 
                         Ok(CastKind::PtrPtrCast)
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7c6bb495be3..7e8e4e3a561 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2060,7 +2060,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // struct-like enums (yet...), but it's definitely not
                 // a bug to have constructed one.
                 if adt_kind != AdtKind::Enum {
-                    tcx.check_stability(v_field.did, Some(expr.hir_id), field.span, None);
+                    tcx.check_stability(v_field.did, Some(field.hir_id), field.span, None);
                 }
 
                 self.field_ty(field.span, v_field, args)
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 63e4a8fb44b..35e687f2b0f 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -1840,7 +1840,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 let ty = self.pat_ty_adjusted(subpat)?;
                 let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability);
                 // A deref pattern generates a temporary.
-                let place = self.cat_rvalue(pat.hir_id, ty);
+                let base = self.cat_rvalue(pat.hir_id, ty);
+                let place = self.cat_deref(pat.hir_id, base)?;
                 self.cat_pattern(place, subpat, op)?;
             }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index b8517701667..96d0a0fc6de 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
-use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
+use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
 use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
@@ -2679,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
                 debug_assert_eq!(params.len(), fn_inputs.len());
                 Some((
-                    fn_inputs.zip(params.iter().map(|param| FnParam::Name(param))).collect(),
+                    fn_inputs.zip(params.iter().map(|&param| FnParam::Name(param))).collect(),
                     generics,
                 ))
             }
@@ -2710,23 +2710,14 @@ impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
 #[derive(Clone, Copy)]
 enum FnParam<'hir> {
     Param(&'hir hir::Param<'hir>),
-    Name(&'hir Ident),
+    Name(Ident),
 }
+
 impl FnParam<'_> {
     fn span(&self) -> Span {
         match self {
-            Self::Param(x) => x.span,
-            Self::Name(x) => x.span,
-        }
-    }
-
-    fn name(&self) -> Option<Symbol> {
-        match self {
-            Self::Param(x) if let hir::PatKind::Binding(_, _, ident, _) = x.pat.kind => {
-                Some(ident.name)
-            }
-            Self::Name(x) if x.name != kw::Empty => Some(x.name),
-            _ => None,
+            Self::Param(param) => param.span,
+            Self::Name(ident) => ident.span,
         }
     }
 
@@ -2734,8 +2725,23 @@ impl FnParam<'_> {
         struct D<'a>(FnParam<'a>, usize);
         impl fmt::Display for D<'_> {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                if let Some(name) = self.0.name() {
-                    write!(f, "`{name}`")
+                // A "unique" param name is one that (a) exists, and (b) is guaranteed to be unique
+                // among the parameters, i.e. `_` does not count.
+                let unique_name = match self.0 {
+                    FnParam::Param(param)
+                        if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind =>
+                    {
+                        Some(ident.name)
+                    }
+                    FnParam::Name(ident)
+                        if ident.name != kw::Empty && ident.name != kw::Underscore =>
+                    {
+                        Some(ident.name)
+                    }
+                    _ => None,
+                };
+                if let Some(unique_name) = unique_name {
+                    write!(f, "`{unique_name}`")
                 } else {
                     write!(f, "parameter #{}", self.1 + 1)
                 }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 7e6973259fe..3d1c61a9c34 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1422,7 +1422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 self.tcx.check_stability(
                     variant.fields[FieldIdx::from_usize(i)].did,
-                    Some(pat.hir_id),
+                    Some(subpat.hir_id),
                     subpat.span,
                     None,
                 );
@@ -1686,7 +1686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .get(&ident)
                         .map(|(i, f)| {
                             self.write_field_index(field.hir_id, *i);
-                            self.tcx.check_stability(f.did, Some(pat.hir_id), span, None);
+                            self.tcx.check_stability(f.did, Some(field.hir_id), span, None);
                             self.field_ty(span, f, args)
                         })
                         .unwrap_or_else(|| {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index aa6eef906ea..8718fb807ec 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -299,6 +299,11 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> {
         intravisit::walk_expr(self, e);
     }
 
+    fn visit_pat_field(&mut self, f: &'tcx hir::PatField<'tcx>) -> Self::Result {
+        self.add_id(f.hir_id);
+        intravisit::walk_pat_field(self, f);
+    }
+
     fn visit_expr_field(&mut self, f: &'tcx hir::ExprField<'tcx>) {
         self.add_id(f.hir_id);
         intravisit::walk_expr_field(self, f);
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 722779d3268..9e4fdd2b3ce 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -274,18 +274,13 @@ impl NonSnakeCase {
             let ident = ident.trim_start_matches('\'');
             let ident = ident.trim_matches('_');
 
-            let mut allow_underscore = true;
-            ident.chars().all(|c| {
-                allow_underscore = match c {
-                    '_' if !allow_underscore => return false,
-                    '_' => false,
-                    // It would be more obvious to use `c.is_lowercase()`,
-                    // but some characters do not have a lowercase form
-                    c if !c.is_uppercase() => true,
-                    _ => return false,
-                };
-                true
-            })
+            if ident.contains("__") {
+                return false;
+            }
+
+            // This correctly handles letters in languages with and without
+            // cases, as well as numbers and underscores.
+            !ident.chars().any(char::is_uppercase)
         }
 
         let name = ident.name.as_str();
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index bc3d4d6f83a..86f1bcc46ee 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1682,12 +1682,21 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
 #endif
 
   // Based on the 'InProcessThinBackend' constructor in LLVM
+#if LLVM_VERSION_GE(21, 0)
+  for (auto &Name : Data->Index.cfiFunctionDefs().symbols())
+    CfiFunctionDefs.insert(
+        GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
+  for (auto &Name : Data->Index.cfiFunctionDecls().symbols())
+    CfiFunctionDecls.insert(
+        GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
+#else
   for (auto &Name : Data->Index.cfiFunctionDefs())
     CfiFunctionDefs.insert(
         GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
   for (auto &Name : Data->Index.cfiFunctionDecls())
     CfiFunctionDecls.insert(
         GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
+#endif
 
 #if LLVM_VERSION_GE(20, 0)
   Key = llvm::computeLTOCacheKey(conf, Data->Index, ModId, ImportList,
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 73c0af84a9f..c61c7a4fb02 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -281,8 +281,9 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Ident> {
-        self.hir_body(id).params.iter().map(|arg| match arg.pat.kind {
+        self.hir_body(id).params.iter().map(|param| match param.pat.kind {
             PatKind::Binding(_, _, ident, _) => ident,
+            PatKind::Wild => Ident::new(kw::Underscore, param.pat.span),
             _ => Ident::empty(),
         })
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 2a3a7705b7b..72924c0dd4b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -63,6 +63,18 @@ thread_local! {
     static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
     static REDUCED_QUERIES: Cell<bool> = const { Cell::new(false) };
     static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
+    static RTN_MODE: Cell<RtnMode> = const { Cell::new(RtnMode::ForDiagnostic) };
+}
+
+/// Rendering style for RTN types.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum RtnMode {
+    /// Print the RTN type as an impl trait with its path, i.e.e `impl Sized { T::method(..) }`.
+    ForDiagnostic,
+    /// Print the RTN type as an impl trait, i.e. `impl Sized`.
+    ForSignature,
+    /// Print the RTN type as a value path, i.e. `T::method(..): ...`.
+    ForSuggestion,
 }
 
 macro_rules! define_helper {
@@ -124,6 +136,38 @@ define_helper!(
     fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
 );
 
+#[must_use]
+pub struct RtnModeHelper(RtnMode);
+
+impl RtnModeHelper {
+    pub fn with(mode: RtnMode) -> RtnModeHelper {
+        RtnModeHelper(RTN_MODE.with(|c| c.replace(mode)))
+    }
+}
+
+impl Drop for RtnModeHelper {
+    fn drop(&mut self) {
+        RTN_MODE.with(|c| c.set(self.0))
+    }
+}
+
+/// Print types for the purposes of a suggestion.
+///
+/// Specifically, this will render RPITITs as `T::method(..)` which is suitable for
+/// things like where-clauses.
+pub macro with_types_for_suggestion($e:expr) {{
+    let _guard = $crate::ty::print::pretty::RtnModeHelper::with(RtnMode::ForSuggestion);
+    $e
+}}
+
+/// Print types for the purposes of a signature suggestion.
+///
+/// Specifically, this will render RPITITs as `impl Trait` rather than `T::method(..)`.
+pub macro with_types_for_signature($e:expr) {{
+    let _guard = $crate::ty::print::pretty::RtnModeHelper::with(RtnMode::ForSignature);
+    $e
+}}
+
 /// Avoids running any queries during prints.
 pub macro with_no_queries($e:expr) {{
     $crate::ty::print::with_reduced_queries!($crate::ty::print::with_forced_impl_filename_line!(
@@ -1223,22 +1267,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
         }
 
-        if self.tcx().features().return_type_notation()
-            && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
-                self.tcx().opt_rpitit_info(def_id)
-            && let ty::Alias(_, alias_ty) =
-                self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind()
-            && alias_ty.def_id == def_id
-            && let generics = self.tcx().generics_of(fn_def_id)
-            // FIXME(return_type_notation): We only support lifetime params for now.
-            && generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
-        {
-            let num_args = generics.count();
-            write!(self, " {{ ")?;
-            self.print_def_path(fn_def_id, &args[..num_args])?;
-            write!(self, "(..) }}")?;
-        }
-
         Ok(())
     }
 
@@ -1306,6 +1334,46 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         )
     }
 
+    fn pretty_print_rpitit(
+        &mut self,
+        def_id: DefId,
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> Result<(), PrintError> {
+        let fn_args = if self.tcx().features().return_type_notation()
+            && let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
+                self.tcx().opt_rpitit_info(def_id)
+            && let ty::Alias(_, alias_ty) =
+                self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind()
+            && alias_ty.def_id == def_id
+            && let generics = self.tcx().generics_of(fn_def_id)
+            // FIXME(return_type_notation): We only support lifetime params for now.
+            && generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
+        {
+            let num_args = generics.count();
+            Some((fn_def_id, &args[..num_args]))
+        } else {
+            None
+        };
+
+        match (fn_args, RTN_MODE.with(|c| c.get())) {
+            (Some((fn_def_id, fn_args)), RtnMode::ForDiagnostic) => {
+                self.pretty_print_opaque_impl_type(def_id, args)?;
+                write!(self, " {{ ")?;
+                self.print_def_path(fn_def_id, fn_args)?;
+                write!(self, "(..) }}")?;
+            }
+            (Some((fn_def_id, fn_args)), RtnMode::ForSuggestion) => {
+                self.print_def_path(fn_def_id, fn_args)?;
+                write!(self, "(..)")?;
+            }
+            _ => {
+                self.pretty_print_opaque_impl_type(def_id, args)?;
+            }
+        }
+
+        Ok(())
+    }
+
     fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> {
         None
     }
@@ -3123,22 +3191,21 @@ define_print! {
     ty::AliasTerm<'tcx> {
         match self.kind(cx.tcx()) {
             ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
-            ty::AliasTermKind::ProjectionTy
-            | ty::AliasTermKind::WeakTy
-            | ty::AliasTermKind::OpaqueTy
-            | ty::AliasTermKind::UnevaluatedConst
-            | ty::AliasTermKind::ProjectionConst => {
-                // If we're printing verbosely, or don't want to invoke queries
-                // (`is_impl_trait_in_trait`), then fall back to printing the def path.
-                // This is likely what you want if you're debugging the compiler anyways.
+            ty::AliasTermKind::ProjectionTy => {
                 if !(cx.should_print_verbose() || with_reduced_queries())
                     && cx.tcx().is_impl_trait_in_trait(self.def_id)
                 {
-                    return cx.pretty_print_opaque_impl_type(self.def_id, self.args);
+                    p!(pretty_print_rpitit(self.def_id, self.args))
                 } else {
                     p!(print_def_path(self.def_id, self.args));
                 }
             }
+            | ty::AliasTermKind::WeakTy
+            | ty::AliasTermKind::OpaqueTy
+            | ty::AliasTermKind::UnevaluatedConst
+            | ty::AliasTermKind::ProjectionConst => {
+                p!(print_def_path(self.def_id, self.args));
+            }
         }
     }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index d78c874c766..7f2e7d5ca83 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -753,6 +753,11 @@ impl UnsafeOpKind {
         span: Span,
         suggest_unsafe_block: bool,
     ) {
+        if tcx.hir_opt_delegation_sig_id(hir_id.owner.def_id).is_some() {
+            // The body of the delegation item is synthesized, so it makes no sense
+            // to emit this lint.
+            return;
+        }
         let parent_id = tcx.hir_get_parent_item(hir_id);
         let parent_owner = tcx.hir_owner_node(parent_id);
         let should_suggest = parent_owner.fn_sig().is_some_and(|sig| {
diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs
index b23d8b9e737..00a8293966b 100644
--- a/compiler/rustc_mir_transform/src/cost_checker.rs
+++ b/compiler/rustc_mir_transform/src/cost_checker.rs
@@ -37,29 +37,11 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
     /// and even the full `Inline` doesn't call `visit_body`, so there's nowhere
     /// to put this logic in the visitor.
     pub(super) fn add_function_level_costs(&mut self) {
-        fn is_call_like(bbd: &BasicBlockData<'_>) -> bool {
-            use TerminatorKind::*;
-            match bbd.terminator().kind {
-                Call { .. } | TailCall { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => {
-                    true
-                }
-
-                Goto { .. }
-                | SwitchInt { .. }
-                | UnwindResume
-                | UnwindTerminate(_)
-                | Return
-                | Unreachable => false,
-
-                Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => {
-                    unreachable!()
-                }
-            }
-        }
-
         // If the only has one Call (or similar), inlining isn't increasing the total
         // number of calls, so give extra encouragement to inlining that.
-        if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd)).count() == 1 {
+        if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd.terminator())).count()
+            == 1
+        {
             self.bonus += CALL_PENALTY;
         }
     }
@@ -193,3 +175,26 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
         }
     }
 }
+
+/// A terminator that's more call-like (might do a bunch of work, might panic, etc)
+/// than it is goto-/return-like (no side effects, etc).
+///
+/// Used to treat multi-call functions (which could inline exponentially)
+/// different from those that only do one or none of these "complex" things.
+pub(super) fn is_call_like(terminator: &Terminator<'_>) -> bool {
+    use TerminatorKind::*;
+    match terminator.kind {
+        Call { .. } | TailCall { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true,
+
+        Goto { .. }
+        | SwitchInt { .. }
+        | UnwindResume
+        | UnwindTerminate(_)
+        | Return
+        | Unreachable => false,
+
+        Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => {
+            unreachable!()
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 0183ba19475..0ab24e48d44 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1,5 +1,6 @@
 //! Inlining pass for MIR functions.
 
+use std::assert_matches::debug_assert_matches;
 use std::iter;
 use std::ops::{Range, RangeFrom};
 
@@ -18,7 +19,7 @@ use rustc_session::config::{DebugInfo, OptLevel};
 use rustc_span::source_map::Spanned;
 use tracing::{debug, instrument, trace, trace_span};
 
-use crate::cost_checker::CostChecker;
+use crate::cost_checker::{CostChecker, is_call_like};
 use crate::deref_separator::deref_finder;
 use crate::simplify::simplify_cfg;
 use crate::validate::validate_types;
@@ -26,6 +27,7 @@ use crate::{check_inline, util};
 
 pub(crate) mod cycle;
 
+const HISTORY_DEPTH_LIMIT: usize = 20;
 const TOP_DOWN_DEPTH_LIMIT: usize = 5;
 
 #[derive(Clone, Debug)]
@@ -117,6 +119,11 @@ trait Inliner<'tcx> {
     /// Should inlining happen for a given callee?
     fn should_inline_for_callee(&self, def_id: DefId) -> bool;
 
+    fn check_codegen_attributes_extra(
+        &self,
+        callee_attrs: &CodegenFnAttrs,
+    ) -> Result<(), &'static str>;
+
     fn check_caller_mir_body(&self, body: &Body<'tcx>) -> bool;
 
     /// Returns inlining decision that is based on the examination of callee MIR body.
@@ -128,10 +135,6 @@ trait Inliner<'tcx> {
         callee_attrs: &CodegenFnAttrs,
     ) -> Result<(), &'static str>;
 
-    // How many callsites in a body are we allowed to inline? We need to limit this in order
-    // to prevent super-linear growth in MIR size.
-    fn inline_limit_for_block(&self) -> Option<usize>;
-
     /// Called when inlining succeeds.
     fn on_inline_success(
         &mut self,
@@ -142,9 +145,6 @@ trait Inliner<'tcx> {
 
     /// Called when inlining failed or was not performed.
     fn on_inline_failure(&self, callsite: &CallSite<'tcx>, reason: &'static str);
-
-    /// Called when the inline limit for a body is reached.
-    fn on_inline_limit_reached(&self) -> bool;
 }
 
 struct ForceInliner<'tcx> {
@@ -191,6 +191,14 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
         ForceInline::should_run_pass_for_callee(self.tcx(), def_id)
     }
 
+    fn check_codegen_attributes_extra(
+        &self,
+        callee_attrs: &CodegenFnAttrs,
+    ) -> Result<(), &'static str> {
+        debug_assert_matches!(callee_attrs.inline, InlineAttr::Force { .. });
+        Ok(())
+    }
+
     fn check_caller_mir_body(&self, _: &Body<'tcx>) -> bool {
         true
     }
@@ -224,10 +232,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
         }
     }
 
-    fn inline_limit_for_block(&self) -> Option<usize> {
-        Some(usize::MAX)
-    }
-
     fn on_inline_success(
         &mut self,
         callsite: &CallSite<'tcx>,
@@ -261,10 +265,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
             justification: justification.map(|sym| crate::errors::ForceInlineJustification { sym }),
         });
     }
-
-    fn on_inline_limit_reached(&self) -> bool {
-        false
-    }
 }
 
 struct NormalInliner<'tcx> {
@@ -278,6 +278,10 @@ struct NormalInliner<'tcx> {
     /// The number of `DefId`s is finite, so checking history is enough
     /// to ensure that we do not loop endlessly while inlining.
     history: Vec<DefId>,
+    /// How many (multi-call) callsites have we inlined for the top-level call?
+    ///
+    /// We need to limit this in order to prevent super-linear growth in MIR size.
+    top_down_counter: usize,
     /// Indicates that the caller body has been modified.
     changed: bool,
     /// Indicates that the caller is #[inline] and just calls another function,
@@ -285,6 +289,12 @@ struct NormalInliner<'tcx> {
     caller_is_inline_forwarder: bool,
 }
 
+impl<'tcx> NormalInliner<'tcx> {
+    fn past_depth_limit(&self) -> bool {
+        self.history.len() > HISTORY_DEPTH_LIMIT || self.top_down_counter > TOP_DOWN_DEPTH_LIMIT
+    }
+}
+
 impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
     fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &Body<'tcx>) -> Self {
         let typing_env = body.typing_env(tcx);
@@ -295,6 +305,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
             typing_env,
             def_id,
             history: Vec::new(),
+            top_down_counter: 0,
             changed: false,
             caller_is_inline_forwarder: matches!(
                 codegen_fn_attrs.inline,
@@ -327,6 +338,17 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
         true
     }
 
+    fn check_codegen_attributes_extra(
+        &self,
+        callee_attrs: &CodegenFnAttrs,
+    ) -> Result<(), &'static str> {
+        if self.past_depth_limit() && matches!(callee_attrs.inline, InlineAttr::None) {
+            Err("Past depth limit so not inspecting unmarked callee")
+        } else {
+            Ok(())
+        }
+    }
+
     fn check_caller_mir_body(&self, body: &Body<'tcx>) -> bool {
         // Avoid inlining into coroutines, since their `optimized_mir` is used for layout computation,
         // which can create a cycle, even when no attempt is made to inline the function in the other
@@ -351,7 +373,11 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
             return Err("body has errors");
         }
 
-        let mut threshold = if self.caller_is_inline_forwarder {
+        if self.past_depth_limit() && callee_body.basic_blocks.len() > 1 {
+            return Err("Not inlining multi-block body as we're past a depth limit");
+        }
+
+        let mut threshold = if self.caller_is_inline_forwarder || self.past_depth_limit() {
             tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30)
         } else if tcx.cross_crate_inlinable(callsite.callee.def_id()) {
             tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100)
@@ -431,14 +457,6 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
         }
     }
 
-    fn inline_limit_for_block(&self) -> Option<usize> {
-        match self.history.len() {
-            0 => Some(usize::MAX),
-            1..=TOP_DOWN_DEPTH_LIMIT => Some(1),
-            _ => None,
-        }
-    }
-
     fn on_inline_success(
         &mut self,
         callsite: &CallSite<'tcx>,
@@ -447,13 +465,21 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
     ) {
         self.changed = true;
 
+        let new_calls_count = new_blocks
+            .clone()
+            .filter(|&bb| is_call_like(caller_body.basic_blocks[bb].terminator()))
+            .count();
+        if new_calls_count > 1 {
+            self.top_down_counter += 1;
+        }
+
         self.history.push(callsite.callee.def_id());
         process_blocks(self, caller_body, new_blocks);
         self.history.pop();
-    }
 
-    fn on_inline_limit_reached(&self) -> bool {
-        true
+        if self.history.is_empty() {
+            self.top_down_counter = 0;
+        }
     }
 
     fn on_inline_failure(&self, _: &CallSite<'tcx>, _: &'static str) {}
@@ -482,8 +508,6 @@ fn process_blocks<'tcx, I: Inliner<'tcx>>(
     caller_body: &mut Body<'tcx>,
     blocks: Range<BasicBlock>,
 ) {
-    let Some(inline_limit) = inliner.inline_limit_for_block() else { return };
-    let mut inlined_count = 0;
     for bb in blocks {
         let bb_data = &caller_body[bb];
         if bb_data.is_cleanup {
@@ -505,13 +529,6 @@ fn process_blocks<'tcx, I: Inliner<'tcx>>(
             Ok(new_blocks) => {
                 debug!("inlined {}", callsite.callee);
                 inliner.on_inline_success(&callsite, caller_body, new_blocks);
-
-                inlined_count += 1;
-                if inlined_count == inline_limit {
-                    if inliner.on_inline_limit_reached() {
-                        return;
-                    }
-                }
             }
         }
     }
@@ -584,6 +601,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
     let callee_attrs = tcx.codegen_fn_attrs(callsite.callee.def_id());
     check_inline::is_inline_valid_on_fn(tcx, callsite.callee.def_id())?;
     check_codegen_attributes(inliner, callsite, callee_attrs)?;
+    inliner.check_codegen_attributes_extra(callee_attrs)?;
 
     let terminator = caller_body[callsite.block].terminator.as_ref().unwrap();
     let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
@@ -770,6 +788,8 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
         return Err("has DoNotOptimize attribute");
     }
 
+    inliner.check_codegen_attributes_extra(callee_attrs)?;
+
     // Reachability pass defines which functions are eligible for inlining. Generally inlining
     // other functions is incorrect because they could reference symbols that aren't exported.
     let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 066b570c23f..53614049f08 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -127,12 +127,29 @@ impl<'a> Parser<'a> {
         let lo = self.token.span;
         // Attributes can't have attributes of their own [Editor's note: not with that attitude]
         self.collect_tokens_no_attrs(|this| {
+            let pound_hi = this.token.span.hi();
             assert!(this.eat(exp!(Pound)), "parse_attribute called in non-attribute position");
 
+            let not_lo = this.token.span.lo();
             let style =
                 if this.eat(exp!(Bang)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
 
-            this.expect(exp!(OpenBracket))?;
+            let mut bracket_res = this.expect(exp!(OpenBracket));
+            // If `#!` is not followed by `[`
+            if let Err(err) = &mut bracket_res
+                && style == ast::AttrStyle::Inner
+                && pound_hi == not_lo
+            {
+                err.note(
+                    "the token sequence `#!` here looks like the start of \
+                    a shebang interpreter directive but it is not",
+                );
+                err.help(
+                    "if you meant this to be a shebang interpreter directive, \
+                    move it to the very start of the file",
+                );
+            }
+            bracket_res?;
             let item = this.parse_attr_item(ForceCollect::No)?;
             this.expect(exp!(CloseBracket))?;
             let attr_sp = lo.to(this.prev_token.span);
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index d28988cd74f..f3f6c551580 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -5117,12 +5117,18 @@ struct ItemInfoCollector<'a, 'ra, 'tcx> {
 }
 
 impl ItemInfoCollector<'_, '_, '_> {
-    fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId, attrs: &[Attribute]) {
+    fn collect_fn_info(
+        &mut self,
+        header: FnHeader,
+        decl: &FnDecl,
+        id: NodeId,
+        attrs: &[Attribute],
+    ) {
         let sig = DelegationFnSig {
-            header: sig.header,
-            param_count: sig.decl.inputs.len(),
-            has_self: sig.decl.has_self(),
-            c_variadic: sig.decl.c_variadic(),
+            header,
+            param_count: decl.inputs.len(),
+            has_self: decl.has_self(),
+            c_variadic: decl.c_variadic(),
             target_feature: attrs.iter().any(|attr| attr.has_name(sym::target_feature)),
         };
         self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);
@@ -5142,7 +5148,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
             | ItemKind::Trait(box Trait { generics, .. })
             | ItemKind::TraitAlias(generics, _) => {
                 if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind {
-                    self.collect_fn_info(sig, item.id, &item.attrs);
+                    self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
                 }
 
                 let def_id = self.r.local_def_id(item.id);
@@ -5154,8 +5160,17 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
                 self.r.item_generics_num_lifetimes.insert(def_id, count);
             }
 
+            ItemKind::ForeignMod(ForeignMod { extern_span, safety: _, abi, items }) => {
+                for foreign_item in items {
+                    if let ForeignItemKind::Fn(box Fn { sig, .. }) = &foreign_item.kind {
+                        let new_header =
+                            FnHeader { ext: Extern::from_abi(*abi, *extern_span), ..sig.header };
+                        self.collect_fn_info(new_header, &sig.decl, foreign_item.id, &item.attrs);
+                    }
+                }
+            }
+
             ItemKind::Mod(..)
-            | ItemKind::ForeignMod(..)
             | ItemKind::Static(..)
             | ItemKind::Use(..)
             | ItemKind::ExternCrate(..)
@@ -5175,7 +5190,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
 
     fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) {
         if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
-            self.collect_fn_info(sig, item.id, &item.attrs);
+            self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
         }
         visit::walk_assoc_item(self, item, ctxt);
     }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index dcdb7fa9c10..34755249b60 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2709,7 +2709,12 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
                 "cdylib" => CrateType::Cdylib,
                 "bin" => CrateType::Executable,
                 "proc-macro" => CrateType::ProcMacro,
-                _ => return Err(format!("unknown crate type: `{part}`")),
+                _ => {
+                    return Err(format!(
+                        "unknown crate type: `{part}`, expected one of: \
+                        `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
+                    ));
+                }
             };
             if !crate_types.contains(&new_part) {
                 crate_types.push(new_part)
diff --git a/compiler/rustc_target/src/spec/base/fuchsia.rs b/compiler/rustc_target/src/spec/base/fuchsia.rs
index 9deafcac27f..92cb0299ddb 100644
--- a/compiler/rustc_target/src/spec/base/fuchsia.rs
+++ b/compiler/rustc_target/src/spec/base/fuchsia.rs
@@ -7,7 +7,7 @@ pub(crate) fn opts() -> TargetOptions {
     // now. When using clang as the linker it will supply these options for us,
     // so we only list them for ld/lld.
     //
-    // https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31
+    // https://github.com/llvm/llvm-project/blob/0419db6b95e246fe9dc90b5795beb77c393eb2ce/clang/lib/Driver/ToolChains/Fuchsia.cpp#L32
     let pre_link_args = TargetOptions::link_args(
         LinkerFlavor::Gnu(Cc::No, Lld::No),
         &[
@@ -18,9 +18,13 @@ pub(crate) fn opts() -> TargetOptions {
             "-z",
             "now",
             "-z",
+            "start-stop-visibility=hidden",
+            "-z",
             "rodynamic",
             "-z",
             "separate-loadable-segments",
+            "-z",
+            "rel",
             "--pack-dyn-relocs=relr",
         ],
     );
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
index 23ed92e62b8..8366b6d9bd8 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs
@@ -1,6 +1,28 @@
-use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, TargetOptions, base};
+use crate::spec::{
+    Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetMetadata, base,
+};
 
 pub(crate) fn target() -> Target {
+    let mut base = base::fuchsia::opts();
+    base.cpu = "generic".into();
+    base.features = "+v8a,+crc,+aes,+sha2,+neon".into();
+    base.max_atomic_width = Some(128);
+    base.stack_probes = StackProbeType::Inline;
+    base.supported_sanitizers = SanitizerSet::ADDRESS
+        | SanitizerSet::CFI
+        | SanitizerSet::LEAK
+        | SanitizerSet::SHADOWCALLSTACK;
+    base.supports_xray = true;
+
+    base.add_pre_link_args(
+        LinkerFlavor::Gnu(Cc::No, Lld::No),
+        &[
+            "--execute-only",
+            // Enable the Cortex-A53 errata 843419 mitigation by default
+            "--fix-cortex-a53-843419",
+        ],
+    );
+
     Target {
         llvm_target: "aarch64-unknown-fuchsia".into(),
         metadata: TargetMetadata {
@@ -12,14 +34,6 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
         arch: "aarch64".into(),
-        options: TargetOptions {
-            features: "+v8a".into(),
-            max_atomic_width: Some(128),
-            stack_probes: StackProbeType::Inline,
-            supported_sanitizers: SanitizerSet::ADDRESS
-                | SanitizerSet::CFI
-                | SanitizerSet::SHADOWCALLSTACK,
-            ..base::fuchsia::opts()
-        },
+        options: base,
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
index 55dc6a70627..8a4bc58e546 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32_wrs_vxworks.rs
@@ -2,7 +2,7 @@ use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        llvm_target: "riscv32".into(),
+        llvm_target: "riscv32-unknown-linux-gnu".into(),
         metadata: TargetMetadata {
             description: None,
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
index 58ded24b9c5..39aa70035e4 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64_wrs_vxworks.rs
@@ -2,7 +2,7 @@ use crate::spec::{StackProbeType, Target, TargetMetadata, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     Target {
-        llvm_target: "riscv64".into(),
+        llvm_target: "riscv64-unknown-linux-gnu".into(),
         metadata: TargetMetadata {
             description: None,
             tier: Some(3),
diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
index d673936f5f8..e260237ca77 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs
@@ -1,6 +1,16 @@
-use crate::spec::{CodeModel, SanitizerSet, Target, TargetMetadata, TargetOptions, base};
+use crate::spec::{CodeModel, SanitizerSet, StackProbeType, Target, TargetMetadata, base};
 
 pub(crate) fn target() -> Target {
+    let mut base = base::fuchsia::opts();
+    base.code_model = Some(CodeModel::Medium);
+    base.cpu = "generic-rv64".into();
+    base.features = "+m,+a,+f,+d,+c".into();
+    base.llvm_abiname = "lp64d".into();
+    base.max_atomic_width = Some(64);
+    base.stack_probes = StackProbeType::Inline;
+    base.supported_sanitizers = SanitizerSet::SHADOWCALLSTACK;
+    base.supports_xray = true;
+
     Target {
         llvm_target: "riscv64-unknown-fuchsia".into(),
         metadata: TargetMetadata {
@@ -12,14 +22,6 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
         arch: "riscv64".into(),
-        options: TargetOptions {
-            code_model: Some(CodeModel::Medium),
-            cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
-            llvm_abiname: "lp64d".into(),
-            max_atomic_width: Some(64),
-            supported_sanitizers: SanitizerSet::SHADOWCALLSTACK,
-            ..base::fuchsia::opts()
-        },
+        options: base,
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
index d41c696ac23..d7253da7e8d 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_fuchsia.rs
@@ -4,7 +4,10 @@ pub(crate) fn target() -> Target {
     let mut base = base::fuchsia::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
-    base.max_atomic_width = Some(64);
+    // See https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs/0073_x86_64_platform_requirement,
+    // which corresponds to x86-64-v2.
+    base.features = "+cx16,+sahf,+popcnt,+sse3,+sse4.1,+sse4.2,+ssse3".into();
+    base.max_atomic_width = Some(128);
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK;
     base.supports_xray = true;
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 6d3b6608ea2..a32b42a6fe3 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -603,13 +603,18 @@ static CSKY_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
 static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     // tidy-alphabetical-start
     ("d", Unstable(sym::loongarch_target_feature), &["f"]),
+    ("div32", Unstable(sym::loongarch_target_feature), &[]),
     ("f", Unstable(sym::loongarch_target_feature), &[]),
     ("frecipe", Unstable(sym::loongarch_target_feature), &[]),
+    ("lam-bh", Unstable(sym::loongarch_target_feature), &[]),
+    ("lamcas", Unstable(sym::loongarch_target_feature), &[]),
     ("lasx", Unstable(sym::loongarch_target_feature), &["lsx"]),
     ("lbt", Unstable(sym::loongarch_target_feature), &[]),
+    ("ld-seq-sa", Unstable(sym::loongarch_target_feature), &[]),
     ("lsx", Unstable(sym::loongarch_target_feature), &["d"]),
     ("lvz", Unstable(sym::loongarch_target_feature), &[]),
     ("relax", Unstable(sym::loongarch_target_feature), &[]),
+    ("scq", Unstable(sym::loongarch_target_feature), &[]),
     ("ual", Unstable(sym::loongarch_target_feature), &[]),
     // tidy-alphabetical-end
 ];
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 4f89f3c2b49..9383b82ff3c 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -26,7 +26,7 @@ use rustc_middle::traits::IsConstable;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::print::{
     PrintPolyTraitPredicateExt as _, PrintPolyTraitRefExt, PrintTraitPredicateExt as _,
-    with_forced_trimmed_paths, with_no_trimmed_paths,
+    with_forced_trimmed_paths, with_no_trimmed_paths, with_types_for_suggestion,
 };
 use rustc_middle::ty::{
     self, AdtKind, GenericArgs, InferTy, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder,
@@ -110,7 +110,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> {
 fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
     (
         generics.tail_span_for_predicate_suggestion(),
-        format!("{} {}", generics.add_where_or_trailing_comma(), pred),
+        with_types_for_suggestion!(format!("{} {}", generics.add_where_or_trailing_comma(), pred)),
     )
 }
 
@@ -136,7 +136,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
     if hir_generics.where_clause_span.from_expansion()
         || hir_generics.where_clause_span.desugaring_kind().is_some()
         || projection.is_some_and(|projection| {
-            tcx.is_impl_trait_in_trait(projection.def_id)
+            (tcx.is_impl_trait_in_trait(projection.def_id)
+                && !tcx.features().return_type_notation())
                 || tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable())
         })
     {
@@ -1997,7 +1998,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 .iter()
                 .enumerate()
                 .map(|(i, ident)| {
-                    if ident.name.is_empty() || ident.name == kw::SelfLower {
+                    if ident.name.is_empty()
+                        || ident.name == kw::Underscore
+                        || ident.name == kw::SelfLower
+                    {
                         format!("arg{i}")
                     } else {
                         format!("{ident}")
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index ead7b2d2965..48b265fabc7 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -90,6 +90,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 // memory, which is not valid for either `&` or `&mut`.
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -99,6 +100,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -108,6 +110,7 @@ pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -117,6 +120,7 @@ pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -126,6 +130,7 @@ pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -135,6 +140,7 @@ pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -144,6 +150,7 @@ pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -153,6 +160,7 @@ pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -162,6 +170,7 @@ pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -171,6 +180,7 @@ pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -180,6 +190,7 @@ pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -189,6 +200,7 @@ pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -198,6 +210,7 @@ pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -207,6 +220,7 @@ pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -216,6 +230,7 @@ pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T)
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange` method by passing
@@ -226,6 +241,7 @@ pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T)
 pub unsafe fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -239,6 +255,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -252,6 +269,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -261,6 +279,7 @@ pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -274,6 +293,7 @@ pub unsafe fn atomic_cxchgweak_acquire_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -287,6 +307,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -296,6 +317,7 @@ pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -309,6 +331,7 @@ pub unsafe fn atomic_cxchgweak_release_relaxed<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -322,6 +345,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
     _src: T,
 ) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -331,6 +355,7 @@ pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -340,6 +365,7 @@ pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -349,6 +375,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -358,6 +385,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -367,6 +395,7 @@ pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -376,6 +405,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 /// Stores a value if the current value is the same as the `old` value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `compare_exchange_weak` method by passing
@@ -386,6 +416,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src:
 pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -394,6 +425,7 @@ pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src:
 #[rustc_nounwind]
 pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -402,6 +434,7 @@ pub unsafe fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
 /// Loads the current value of the pointer.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `load` method by passing
@@ -417,6 +450,7 @@ pub unsafe fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
 pub unsafe fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
 
 /// Stores the value at the specified memory location.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -425,6 +459,7 @@ pub unsafe fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
 /// Stores the value at the specified memory location.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -433,6 +468,7 @@ pub unsafe fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
 #[rustc_nounwind]
 pub unsafe fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
 /// Stores the value at the specified memory location.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `store` method by passing
@@ -448,6 +484,7 @@ pub unsafe fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
 pub unsafe fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
 
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -456,6 +493,7 @@ pub unsafe fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -464,6 +502,7 @@ pub unsafe fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -472,6 +511,7 @@ pub unsafe fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -480,6 +520,7 @@ pub unsafe fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Stores the value at the specified memory location, returning the old value.
+/// `T` must be an integer or pointer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `swap` method by passing
@@ -489,6 +530,9 @@ pub unsafe fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -497,6 +541,9 @@ pub unsafe fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -505,6 +552,9 @@ pub unsafe fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -513,6 +563,9 @@ pub unsafe fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -521,6 +574,9 @@ pub unsafe fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Adds to the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_add` method by passing
@@ -530,6 +586,9 @@ pub unsafe fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -538,6 +597,9 @@ pub unsafe fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -546,6 +608,9 @@ pub unsafe fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -554,6 +619,9 @@ pub unsafe fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -562,6 +630,9 @@ pub unsafe fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Subtract from the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_sub` method by passing
@@ -571,6 +642,9 @@ pub unsafe fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -579,6 +653,9 @@ pub unsafe fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -587,6 +664,9 @@ pub unsafe fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -595,6 +675,9 @@ pub unsafe fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -603,6 +686,9 @@ pub unsafe fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise and with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_and` method by passing
@@ -612,6 +698,9 @@ pub unsafe fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -620,6 +709,9 @@ pub unsafe fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -628,6 +720,9 @@ pub unsafe fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -636,6 +731,9 @@ pub unsafe fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -644,6 +742,9 @@ pub unsafe fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise nand with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`AtomicBool`] type via the `fetch_nand` method by passing
@@ -653,6 +754,9 @@ pub unsafe fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -661,6 +765,9 @@ pub unsafe fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -669,6 +776,9 @@ pub unsafe fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -677,6 +787,9 @@ pub unsafe fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -685,6 +798,9 @@ pub unsafe fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise or with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_or` method by passing
@@ -694,6 +810,9 @@ pub unsafe fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -702,6 +821,9 @@ pub unsafe fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -710,6 +832,9 @@ pub unsafe fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -718,6 +843,9 @@ pub unsafe fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -726,6 +854,9 @@ pub unsafe fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Bitwise xor with the current value, returning the previous value.
+/// `T` must be an integer or pointer type.
+/// If `T` is a pointer type, the provenance of `src` is ignored: both the return value and the new
+/// value stored at `*dst` will have the provenance of the old value stored there.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] types via the `fetch_xor` method by passing
@@ -735,6 +866,7 @@ pub unsafe fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -743,6 +875,7 @@ pub unsafe fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -751,6 +884,7 @@ pub unsafe fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -759,6 +893,7 @@ pub unsafe fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -766,7 +901,8 @@ pub unsafe fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_intrinsic]
 #[rustc_nounwind]
 pub unsafe fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-/// Maximum with the current value.
+/// Maximum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_max` method by passing
@@ -776,6 +912,7 @@ pub unsafe fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -784,6 +921,7 @@ pub unsafe fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -792,6 +930,7 @@ pub unsafe fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -800,6 +939,7 @@ pub unsafe fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -808,6 +948,7 @@ pub unsafe fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using a signed comparison.
+/// `T` must be a signed integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] signed integer types via the `fetch_min` method by passing
@@ -817,6 +958,7 @@ pub unsafe fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -825,6 +967,7 @@ pub unsafe fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -833,6 +976,7 @@ pub unsafe fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -841,6 +985,7 @@ pub unsafe fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -849,6 +994,7 @@ pub unsafe fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Minimum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
@@ -858,6 +1004,7 @@ pub unsafe fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 pub unsafe fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -866,6 +1013,7 @@ pub unsafe fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -874,6 +1022,7 @@ pub unsafe fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -882,6 +1031,7 @@ pub unsafe fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
@@ -890,6 +1040,7 @@ pub unsafe fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
 /// Maximum with the current value using an unsigned comparison.
+/// `T` must be an unsigned integer type.
 ///
 /// The stabilized version of this intrinsic is available on the
 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index e234f105b0b..a4ab4674f4a 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -465,9 +465,13 @@ impl<T: ?Sized> Copy for &T {}
 /// Notably, this doesn't include all trivially-destructible types for semver
 /// reasons.
 ///
-/// Bikeshed name for now.
+/// Bikeshed name for now. This trait does not do anything other than reflect the
+/// set of types that are allowed within unions for field validity.
 #[unstable(feature = "bikeshed_guaranteed_no_drop", issue = "none")]
 #[lang = "bikeshed_guaranteed_no_drop"]
+#[rustc_deny_explicit_impl]
+#[rustc_do_not_implement_via_object]
+#[doc(hidden)]
 pub trait BikeshedGuaranteedNoDrop {}
 
 /// Types for which it is safe to share references between threads.
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index caab7a6ddb5..1494d7aca15 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -856,8 +856,13 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
     // such that the old value is not duplicated. Nothing is dropped and
     // nothing here can panic.
     unsafe {
-        let result = ptr::read(dest);
-        ptr::write(dest, src);
+        // Ideally we wouldn't use the intrinsics here, but going through the
+        // `ptr` methods introduces two unnecessary UbChecks, so until we can
+        // remove those for pointers that come from references, this uses the
+        // intrinsics instead so this stays very cheap in MIR (and debug).
+
+        let result = crate::intrinsics::read_via_copy(dest);
+        crate::intrinsics::write_via_move(dest, src);
         result
     }
 }
diff --git a/library/core/src/net/socket_addr.rs b/library/core/src/net/socket_addr.rs
index 57f47e66e81..21753d00924 100644
--- a/library/core/src/net/socket_addr.rs
+++ b/library/core/src/net/socket_addr.rs
@@ -8,11 +8,15 @@ use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
 /// [`SocketAddrV6`]'s respective documentation for more details.
 ///
-/// The size of a `SocketAddr` instance may vary depending on the target operating
-/// system.
-///
 /// [IP address]: IpAddr
 ///
+/// # Portability
+///
+/// `SocketAddr` is intended to be a portable representation of socket addresses and is likely not
+/// the same as the internal socket address type used by the target operating system's API. Like all
+/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
+/// between builds.
+///
 /// # Examples
 ///
 /// ```
@@ -42,13 +46,16 @@ pub enum SocketAddr {
 ///
 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
 ///
-/// The size of a `SocketAddrV4` struct may vary depending on the target operating
-/// system. Do not assume that this type has the same memory layout as the underlying
-/// system representation.
-///
 /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
 /// [`IPv4` address]: Ipv4Addr
 ///
+/// # Portability
+///
+/// `SocketAddrV4` is intended to be a portable representation of socket addresses and is likely not
+/// the same as the internal socket address type used by the target operating system's API. Like all
+/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
+/// between builds.
+///
 /// # Textual representation
 ///
 /// `SocketAddrV4` provides a [`FromStr`](crate::str::FromStr) implementation.
@@ -84,13 +91,16 @@ pub struct SocketAddrV4 {
 ///
 /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
 ///
-/// The size of a `SocketAddrV6` struct may vary depending on the target operating
-/// system. Do not assume that this type has the same memory layout as the underlying
-/// system representation.
-///
 /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
 /// [`IPv6` address]: Ipv6Addr
 ///
+/// # Portability
+///
+/// `SocketAddrV6` is intended to be a portable representation of socket addresses and is likely not
+/// the same as the internal socket address type used by the target operating system's API. Like all
+/// `repr(Rust)` structs, however, its exact layout remains undefined and should not be relied upon
+/// between builds.
+///
 /// # Textual representation
 ///
 /// `SocketAddrV6` provides a [`FromStr`](crate::str::FromStr) implementation,
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 9a4f916803e..7d0839aff3f 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -193,7 +193,6 @@ impl<T: ?Sized> *const T {
     /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
     ///
     /// [`with_exposed_provenance`]: with_exposed_provenance
-    #[must_use]
     #[inline(always)]
     #[stable(feature = "exposed_provenance", since = "1.84.0")]
     pub fn expose_provenance(self) -> usize {
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index ff4a4b35ce4..2487f5a2a50 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -208,20 +208,32 @@ use crate::ops::Index;
 /// # Usage in `const` and `static`
 ///
 /// As explained above, `HashMap` is randomly seeded: each `HashMap` instance uses a different seed,
-/// which means that `HashMap::new` cannot be used in const context. To construct a `HashMap` in the
-/// initializer of a `const` or `static` item, you will have to use a different hasher that does not
-/// involve a random seed, as demonstrated in the following example. **A `HashMap` constructed this
-/// way is not resistant against HashDoS!**
+/// which means that `HashMap::new` normally cannot be used in a `const` or `static` initializer.
 ///
+/// However, if you need to use a `HashMap` in a `const` or `static` initializer while retaining
+/// random seed generation, you can wrap the `HashMap` in [`LazyLock`].
+///
+/// Alternatively, you can construct a `HashMap` in a `const` or `static` initializer using a different
+/// hasher that does not rely on a random seed. **Be aware that a `HashMap` created this way is not
+/// resistant to HashDoS attacks!**
+///
+/// [`LazyLock`]: crate::sync::LazyLock
 /// ```rust
 /// use std::collections::HashMap;
 /// use std::hash::{BuildHasherDefault, DefaultHasher};
-/// use std::sync::Mutex;
+/// use std::sync::{LazyLock, Mutex};
 ///
-/// const EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> =
+/// // HashMaps with a fixed, non-random hasher
+/// const NONRANDOM_EMPTY_MAP: HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>> =
 ///     HashMap::with_hasher(BuildHasherDefault::new());
-/// static MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> =
+/// static NONRANDOM_MAP: Mutex<HashMap<String, Vec<i32>, BuildHasherDefault<DefaultHasher>>> =
 ///     Mutex::new(HashMap::with_hasher(BuildHasherDefault::new()));
+///
+/// // HashMaps using LazyLock to retain random seeding
+/// const RANDOM_EMPTY_MAP: LazyLock<HashMap<String, Vec<i32>>> =
+///     LazyLock::new(HashMap::new);
+/// static RANDOM_MAP: LazyLock<Mutex<HashMap<String, Vec<i32>>>> =
+///     LazyLock::new(|| Mutex::new(HashMap::new()));
 /// ```
 
 #[cfg_attr(not(test), rustc_diagnostic_item = "HashMap")]
@@ -1278,69 +1290,6 @@ where
     }
 }
 
-impl<K, V, S> HashMap<K, V, S>
-where
-    S: BuildHasher,
-{
-    /// Creates a raw entry builder for the `HashMap`.
-    ///
-    /// Raw entries provide the lowest level of control for searching and
-    /// manipulating a map. They must be manually initialized with a hash and
-    /// then manually searched. After this, insertions into a vacant entry
-    /// still require an owned key to be provided.
-    ///
-    /// Raw entries are useful for such exotic situations as:
-    ///
-    /// * Hash memoization
-    /// * Deferring the creation of an owned key until it is known to be required
-    /// * Using a search key that doesn't work with the Borrow trait
-    /// * Using custom comparison logic without newtype wrappers
-    ///
-    /// Because raw entries provide much more low-level control, it's much easier
-    /// to put the `HashMap` into an inconsistent state which, while memory-safe,
-    /// will cause the map to produce seemingly random results. Higher-level and
-    /// more foolproof APIs like `entry` should be preferred when possible.
-    ///
-    /// In particular, the hash used to initialize the raw entry must still be
-    /// consistent with the hash of the key that is ultimately stored in the entry.
-    /// This is because implementations of `HashMap` may need to recompute hashes
-    /// when resizing, at which point only the keys are available.
-    ///
-    /// Raw entries give mutable access to the keys. This must not be used
-    /// to modify how the key would compare or hash, as the map will not re-evaluate
-    /// where the key should go, meaning the keys may become "lost" if their
-    /// location does not reflect their state. For instance, if you change a key
-    /// so that the map now contains keys which compare equal, search may start
-    /// acting erratically, with two keys randomly masking each other. Implementations
-    /// are free to assume this doesn't happen (within the limits of memory-safety).
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
-        RawEntryBuilderMut { map: self }
-    }
-
-    /// Creates a raw immutable entry builder for the `HashMap`.
-    ///
-    /// Raw entries provide the lowest level of control for searching and
-    /// manipulating a map. They must be manually initialized with a hash and
-    /// then manually searched.
-    ///
-    /// This is useful for
-    /// * Hash memoization
-    /// * Using a search key that doesn't work with the Borrow trait
-    /// * Using custom comparison logic without newtype wrappers
-    ///
-    /// Unless you are in such a situation, higher-level and more foolproof APIs like
-    /// `get` should be preferred.
-    ///
-    /// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S> {
-        RawEntryBuilder { map: self }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S> Clone for HashMap<K, V, S>
 where
@@ -1828,404 +1777,6 @@ impl<K, V> Default for IntoValues<K, V> {
     }
 }
 
-/// A builder for computing where in a HashMap a key-value pair would be stored.
-///
-/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
-    map: &'a mut HashMap<K, V, S>,
-}
-
-/// A view into a single entry in a map, which may either be vacant or occupied.
-///
-/// This is a lower-level version of [`Entry`].
-///
-/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
-/// then calling one of the methods of that [`RawEntryBuilderMut`].
-///
-/// [`raw_entry_mut`]: HashMap::raw_entry_mut
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
-    /// An occupied entry.
-    Occupied(RawOccupiedEntryMut<'a, K, V, S>),
-    /// A vacant entry.
-    Vacant(RawVacantEntryMut<'a, K, V, S>),
-}
-
-/// A view into an occupied entry in a `HashMap`.
-/// It is part of the [`RawEntryMut`] enum.
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-pub struct RawOccupiedEntryMut<'a, K: 'a, V: 'a, S: 'a> {
-    base: base::RawOccupiedEntryMut<'a, K, V, S>,
-}
-
-/// A view into a vacant entry in a `HashMap`.
-/// It is part of the [`RawEntryMut`] enum.
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> {
-    base: base::RawVacantEntryMut<'a, K, V, S>,
-}
-
-/// A builder for computing where in a HashMap a key-value pair would be stored.
-///
-/// See the [`HashMap::raw_entry`] docs for usage examples.
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> {
-    map: &'a HashMap<K, V, S>,
-}
-
-impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
-where
-    S: BuildHasher,
-{
-    /// Creates a `RawEntryMut` from the given key.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_key<Q: ?Sized>(self, k: &Q) -> RawEntryMut<'a, K, V, S>
-    where
-        K: Borrow<Q>,
-        Q: Hash + Eq,
-    {
-        map_raw_entry(self.map.base.raw_entry_mut().from_key(k))
-    }
-
-    /// Creates a `RawEntryMut` from the given key and its hash.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S>
-    where
-        K: Borrow<Q>,
-        Q: Eq,
-    {
-        map_raw_entry(self.map.base.raw_entry_mut().from_key_hashed_nocheck(hash, k))
-    }
-
-    /// Creates a `RawEntryMut` from the given hash.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
-    where
-        for<'b> F: FnMut(&'b K) -> bool,
-    {
-        map_raw_entry(self.map.base.raw_entry_mut().from_hash(hash, is_match))
-    }
-}
-
-impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
-where
-    S: BuildHasher,
-{
-    /// Access an entry by key.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_key<Q: ?Sized>(self, k: &Q) -> Option<(&'a K, &'a V)>
-    where
-        K: Borrow<Q>,
-        Q: Hash + Eq,
-    {
-        self.map.base.raw_entry().from_key(k)
-    }
-
-    /// Access an entry by a key and its hash.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
-    where
-        K: Borrow<Q>,
-        Q: Hash + Eq,
-    {
-        self.map.base.raw_entry().from_key_hashed_nocheck(hash, k)
-    }
-
-    /// Access an entry by hash.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
-    where
-        F: FnMut(&K) -> bool,
-    {
-        self.map.base.raw_entry().from_hash(hash, is_match)
-    }
-}
-
-impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
-    /// Ensures a value is in the entry by inserting the default if empty, and returns
-    /// mutable references to the key and value in the entry.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(hash_raw_entry)]
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<&str, u32> = HashMap::new();
-    ///
-    /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3);
-    /// assert_eq!(map["poneyland"], 3);
-    ///
-    /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2;
-    /// assert_eq!(map["poneyland"], 6);
-    /// ```
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
-    where
-        K: Hash,
-        S: BuildHasher,
-    {
-        match self {
-            RawEntryMut::Occupied(entry) => entry.into_key_value(),
-            RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val),
-        }
-    }
-
-    /// Ensures a value is in the entry by inserting the result of the default function if empty,
-    /// and returns mutable references to the key and value in the entry.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(hash_raw_entry)]
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<&str, String> = HashMap::new();
-    ///
-    /// map.raw_entry_mut().from_key("poneyland").or_insert_with(|| {
-    ///     ("poneyland", "hoho".to_string())
-    /// });
-    ///
-    /// assert_eq!(map["poneyland"], "hoho".to_string());
-    /// ```
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
-    where
-        F: FnOnce() -> (K, V),
-        K: Hash,
-        S: BuildHasher,
-    {
-        match self {
-            RawEntryMut::Occupied(entry) => entry.into_key_value(),
-            RawEntryMut::Vacant(entry) => {
-                let (k, v) = default();
-                entry.insert(k, v)
-            }
-        }
-    }
-
-    /// Provides in-place mutable access to an occupied entry before any
-    /// potential inserts into the map.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(hash_raw_entry)]
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<&str, u32> = HashMap::new();
-    ///
-    /// map.raw_entry_mut()
-    ///    .from_key("poneyland")
-    ///    .and_modify(|_k, v| { *v += 1 })
-    ///    .or_insert("poneyland", 42);
-    /// assert_eq!(map["poneyland"], 42);
-    ///
-    /// map.raw_entry_mut()
-    ///    .from_key("poneyland")
-    ///    .and_modify(|_k, v| { *v += 1 })
-    ///    .or_insert("poneyland", 0);
-    /// assert_eq!(map["poneyland"], 43);
-    /// ```
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn and_modify<F>(self, f: F) -> Self
-    where
-        F: FnOnce(&mut K, &mut V),
-    {
-        match self {
-            RawEntryMut::Occupied(mut entry) => {
-                {
-                    let (k, v) = entry.get_key_value_mut();
-                    f(k, v);
-                }
-                RawEntryMut::Occupied(entry)
-            }
-            RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
-        }
-    }
-}
-
-impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
-    /// Gets a reference to the key in the entry.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn key(&self) -> &K {
-        self.base.key()
-    }
-
-    /// Gets a mutable reference to the key in the entry.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn key_mut(&mut self) -> &mut K {
-        self.base.key_mut()
-    }
-
-    /// Converts the entry into a mutable reference to the key in the entry
-    /// with a lifetime bound to the map itself.
-    #[inline]
-    #[must_use = "`self` will be dropped if the result is not used"]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn into_key(self) -> &'a mut K {
-        self.base.into_key()
-    }
-
-    /// Gets a reference to the value in the entry.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn get(&self) -> &V {
-        self.base.get()
-    }
-
-    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
-    /// with a lifetime bound to the map itself.
-    #[inline]
-    #[must_use = "`self` will be dropped if the result is not used"]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn into_mut(self) -> &'a mut V {
-        self.base.into_mut()
-    }
-
-    /// Gets a mutable reference to the value in the entry.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn get_mut(&mut self) -> &mut V {
-        self.base.get_mut()
-    }
-
-    /// Gets a reference to the key and value in the entry.
-    #[inline]
-    #[must_use]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn get_key_value(&mut self) -> (&K, &V) {
-        self.base.get_key_value()
-    }
-
-    /// Gets a mutable reference to the key and value in the entry.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
-        self.base.get_key_value_mut()
-    }
-
-    /// Converts the `OccupiedEntry` into a mutable reference to the key and value in the entry
-    /// with a lifetime bound to the map itself.
-    #[inline]
-    #[must_use = "`self` will be dropped if the result is not used"]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
-        self.base.into_key_value()
-    }
-
-    /// Sets the value of the entry, and returns the entry's old value.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn insert(&mut self, value: V) -> V {
-        self.base.insert(value)
-    }
-
-    /// Sets the value of the entry, and returns the entry's old value.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn insert_key(&mut self, key: K) -> K {
-        self.base.insert_key(key)
-    }
-
-    /// Takes the value out of the entry, and returns it.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn remove(self) -> V {
-        self.base.remove()
-    }
-
-    /// Take the ownership of the key and value from the map.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn remove_entry(self) -> (K, V) {
-        self.base.remove_entry()
-    }
-}
-
-impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
-    /// Sets the value of the entry with the `VacantEntry`'s key,
-    /// and returns a mutable reference to it.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
-    where
-        K: Hash,
-        S: BuildHasher,
-    {
-        self.base.insert(key, value)
-    }
-
-    /// Sets the value of the entry with the VacantEntry's key,
-    /// and returns a mutable reference to it.
-    #[inline]
-    #[unstable(feature = "hash_raw_entry", issue = "56167")]
-    pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V)
-    where
-        K: Hash,
-        S: BuildHasher,
-    {
-        self.base.insert_hashed_nocheck(hash, key, value)
-    }
-}
-
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-impl<K, V, S> Debug for RawEntryBuilderMut<'_, K, V, S> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
-    }
-}
-
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-impl<K: Debug, V: Debug, S> Debug for RawEntryMut<'_, K, V, S> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
-            RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
-        }
-    }
-}
-
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-impl<K: Debug, V: Debug, S> Debug for RawOccupiedEntryMut<'_, K, V, S> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("RawOccupiedEntryMut")
-            .field("key", self.key())
-            .field("value", self.get())
-            .finish_non_exhaustive()
-    }
-}
-
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-impl<K, V, S> Debug for RawVacantEntryMut<'_, K, V, S> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("RawVacantEntryMut").finish_non_exhaustive()
-    }
-}
-
-#[unstable(feature = "hash_raw_entry", issue = "56167")]
-impl<K, V, S> Debug for RawEntryBuilder<'_, K, V, S> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
-    }
-}
-
 /// A view into a single entry in a map, which may either be vacant or occupied.
 ///
 /// This `enum` is constructed from the [`entry`] method on [`HashMap`].
@@ -3298,16 +2849,6 @@ pub(super) fn map_try_reserve_error(err: hashbrown::TryReserveError) -> TryReser
     }
 }
 
-#[inline]
-fn map_raw_entry<'a, K: 'a, V: 'a, S: 'a>(
-    raw: base::RawEntryMut<'a, K, V, S>,
-) -> RawEntryMut<'a, K, V, S> {
-    match raw {
-        base::RawEntryMut::Occupied(base) => RawEntryMut::Occupied(RawOccupiedEntryMut { base }),
-        base::RawEntryMut::Vacant(base) => RawEntryMut::Vacant(RawVacantEntryMut { base }),
-    }
-}
-
 #[allow(dead_code)]
 fn assert_covariance() {
     fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> {
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index a275488a556..9f7df20a1d7 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -852,99 +852,6 @@ fn test_try_reserve() {
     }
 }
 
-#[test]
-fn test_raw_entry() {
-    use super::RawEntryMut::{Occupied, Vacant};
-
-    let xs = [(1i32, 10i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-    let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-    let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
-        use core::hash::{BuildHasher, Hash, Hasher};
-
-        let mut hasher = map.hasher().build_hasher();
-        k.hash(&mut hasher);
-        hasher.finish()
-    };
-
-    // Existing key (insert)
-    match map.raw_entry_mut().from_key(&1) {
-        Vacant(_) => unreachable!(),
-        Occupied(mut view) => {
-            assert_eq!(view.get(), &10);
-            assert_eq!(view.insert(100), 10);
-        }
-    }
-    let hash1 = compute_hash(&map, 1);
-    assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
-    assert_eq!(map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(), (&1, &100));
-    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(), (&1, &100));
-    assert_eq!(map.len(), 6);
-
-    // Existing key (update)
-    match map.raw_entry_mut().from_key(&2) {
-        Vacant(_) => unreachable!(),
-        Occupied(mut view) => {
-            let v = view.get_mut();
-            let new_v = (*v) * 10;
-            *v = new_v;
-        }
-    }
-    let hash2 = compute_hash(&map, 2);
-    assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
-    assert_eq!(map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(), (&2, &200));
-    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(), (&2, &200));
-    assert_eq!(map.len(), 6);
-
-    // Existing key (take)
-    let hash3 = compute_hash(&map, 3);
-    match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
-        Vacant(_) => unreachable!(),
-        Occupied(view) => {
-            assert_eq!(view.remove_entry(), (3, 30));
-        }
-    }
-    assert_eq!(map.raw_entry().from_key(&3), None);
-    assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
-    assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
-    assert_eq!(map.len(), 5);
-
-    // Nonexistent key (insert)
-    match map.raw_entry_mut().from_key(&10) {
-        Occupied(_) => unreachable!(),
-        Vacant(view) => {
-            assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
-        }
-    }
-    assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
-    assert_eq!(map.len(), 6);
-
-    // Ensure all lookup methods produce equivalent results.
-    for k in 0..12 {
-        let hash = compute_hash(&map, k);
-        let v = map.get(&k).cloned();
-        let kv = v.as_ref().map(|v| (&k, v));
-
-        assert_eq!(map.raw_entry().from_key(&k), kv);
-        assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
-        assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
-
-        match map.raw_entry_mut().from_key(&k) {
-            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-            Vacant(_) => assert_eq!(v, None),
-        }
-        match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
-            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-            Vacant(_) => assert_eq!(v, None),
-        }
-        match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
-            Occupied(mut o) => assert_eq!(Some(o.get_key_value()), kv),
-            Vacant(_) => assert_eq!(v, None),
-        }
-    }
-}
-
 mod test_extract_if {
     use super::*;
     use crate::panic::{AssertUnwindSafe, catch_unwind};
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 04a45fd035a..0427feb2955 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -276,63 +276,89 @@ impl FileExt for fs::File {
 }
 
 /// Unix-specific extensions to [`fs::Permissions`].
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::fs::{File, Permissions};
+/// use std::io::{ErrorKind, Result as IoResult};
+/// use std::os::unix::fs::PermissionsExt;
+///
+/// fn main() -> IoResult<()> {
+///     let name = "test_file_for_permissions";
+///
+///     // make sure file does not exist
+///     let _ = std::fs::remove_file(name);
+///     assert_eq!(
+///         File::open(name).unwrap_err().kind(),
+///         ErrorKind::NotFound,
+///         "file already exists"
+///     );
+///
+///     // full read/write/execute mode bits for owner of file
+///     // that we want to add to existing mode bits
+///     let my_mode = 0o700;
+///
+///     // create new file with specified permissions
+///     {
+///         let file = File::create(name)?;
+///         let mut permissions = file.metadata()?.permissions();
+///         eprintln!("Current permissions: {:o}", permissions.mode());
+///
+///         // make sure new permissions are not already set
+///         assert!(
+///             permissions.mode() & my_mode != my_mode,
+///             "permissions already set"
+///         );
+///
+///         // either use `set_mode` to change an existing Permissions struct
+///         permissions.set_mode(permissions.mode() | my_mode);
+///
+///         // or use `from_mode` to construct a new Permissions struct
+///         permissions = Permissions::from_mode(permissions.mode() | my_mode);
+///
+///         // write new permissions to file
+///         file.set_permissions(permissions)?;
+///     }
+///
+///     let permissions = File::open(name)?.metadata()?.permissions();
+///     eprintln!("New permissions: {:o}", permissions.mode());
+///
+///     // assert new permissions were set
+///     assert_eq!(
+///         permissions.mode() & my_mode,
+///         my_mode,
+///         "new permissions not set"
+///     );
+///     Ok(())
+/// }
+/// ```
+///
+/// ```no_run
+/// use std::fs::Permissions;
+/// use std::os::unix::fs::PermissionsExt;
+///
+/// // read/write for owner and read for others
+/// let my_mode = 0o644;
+/// let mut permissions = Permissions::from_mode(my_mode);
+/// assert_eq!(permissions.mode(), my_mode);
+///
+/// // read/write/execute for owner
+/// let other_mode = 0o700;
+/// permissions.set_mode(other_mode);
+/// assert_eq!(permissions.mode(), other_mode);
+/// ```
 #[stable(feature = "fs_ext", since = "1.1.0")]
 pub trait PermissionsExt {
-    /// Returns the underlying raw `st_mode` bits that contain the standard
-    /// Unix permissions for this file.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::os::unix::fs::PermissionsExt;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let f = File::create("foo.txt")?;
-    ///     let metadata = f.metadata()?;
-    ///     let permissions = metadata.permissions();
-    ///
-    ///     println!("permissions: {:o}", permissions.mode());
-    ///     Ok(())
-    /// }
-    /// ```
+    /// Returns the mode permission bits
     #[stable(feature = "fs_ext", since = "1.1.0")]
     fn mode(&self) -> u32;
 
-    /// Sets the underlying raw bits for this set of permissions.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::os::unix::fs::PermissionsExt;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let f = File::create("foo.txt")?;
-    ///     let metadata = f.metadata()?;
-    ///     let mut permissions = metadata.permissions();
-    ///
-    ///     permissions.set_mode(0o644); // Read/write for owner and read for others.
-    ///     assert_eq!(permissions.mode(), 0o644);
-    ///     Ok(())
-    /// }
-    /// ```
+    /// Sets the mode permission bits.
     #[stable(feature = "fs_ext", since = "1.1.0")]
     fn set_mode(&mut self, mode: u32);
 
-    /// Creates a new instance of `Permissions` from the given set of Unix
-    /// permission bits.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::fs::Permissions;
-    /// use std::os::unix::fs::PermissionsExt;
-    ///
-    /// // Read/write for owner and read for others.
-    /// let permissions = Permissions::from_mode(0o644);
-    /// assert_eq!(permissions.mode(), 0o644);
-    /// ```
+    /// Creates a new instance from the given mode permission bits.
     #[stable(feature = "fs_ext", since = "1.1.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "permissions_from_mode")]
     fn from_mode(mode: u32) -> Self;
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index f9f3b488f0d..980213be7ea 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -294,11 +294,6 @@ where
     }
 }
 
-// Detect scheme on Redox
-pub(crate) fn has_redox_scheme(s: &[u8]) -> bool {
-    cfg!(target_os = "redox") && s.contains(&b':')
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Cross-platform, iterator-independent parsing
 ////////////////////////////////////////////////////////////////////////////////
@@ -2834,8 +2829,7 @@ impl Path {
         Components {
             path: self.as_u8_slice(),
             prefix,
-            has_physical_root: has_physical_root(self.as_u8_slice(), prefix)
-                || has_redox_scheme(self.as_u8_slice()),
+            has_physical_root: has_physical_root(self.as_u8_slice(), prefix),
             front: State::Prefix,
             back: State::Body,
         }
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 0a2a8f5ef67..60c33c637d7 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -216,6 +216,60 @@ pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::R
     Err(io::const_error!(io::ErrorKind::NotFound, "no device path to text protocol found"))
 }
 
+fn device_node_to_text(path: NonNull<device_path::Protocol>) -> io::Result<OsString> {
+    fn node_to_text(
+        protocol: NonNull<device_path_to_text::Protocol>,
+        path: NonNull<device_path::Protocol>,
+    ) -> io::Result<OsString> {
+        let path_ptr: *mut r_efi::efi::Char16 = unsafe {
+            ((*protocol.as_ptr()).convert_device_node_to_text)(
+                path.as_ptr(),
+                // DisplayOnly
+                r_efi::efi::Boolean::FALSE,
+                // AllowShortcuts
+                r_efi::efi::Boolean::FALSE,
+            )
+        };
+
+        let path = os_string_from_raw(path_ptr)
+            .ok_or(io::const_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
+
+        if let Some(boot_services) = crate::os::uefi::env::boot_services() {
+            let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+            unsafe {
+                ((*boot_services.as_ptr()).free_pool)(path_ptr.cast());
+            }
+        }
+
+        Ok(path)
+    }
+
+    static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
+        AtomicPtr::new(crate::ptr::null_mut());
+
+    if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
+        if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
+            handle,
+            device_path_to_text::PROTOCOL_GUID,
+        ) {
+            return node_to_text(protocol, path);
+        }
+    }
+
+    let device_path_to_text_handles = locate_handles(device_path_to_text::PROTOCOL_GUID)?;
+    for handle in device_path_to_text_handles {
+        if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
+            handle,
+            device_path_to_text::PROTOCOL_GUID,
+        ) {
+            LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
+            return node_to_text(protocol, path);
+        }
+    }
+
+    Err(io::const_error!(io::ErrorKind::NotFound, "No device path to text protocol found"))
+}
+
 /// Gets RuntimeServices.
 pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>> {
     let system_table: NonNull<r_efi::efi::SystemTable> =
@@ -319,6 +373,11 @@ impl<'a> BorrowedDevicePath<'a> {
     pub(crate) fn to_text(&self) -> io::Result<OsString> {
         device_path_to_text(self.protocol)
     }
+
+    #[expect(dead_code)]
+    pub(crate) const fn iter(&'a self) -> DevicePathIterator<'a> {
+        DevicePathIterator::new(DevicePathNode::new(self.protocol))
+    }
 }
 
 impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> {
@@ -330,6 +389,126 @@ impl<'a> crate::fmt::Debug for BorrowedDevicePath<'a> {
     }
 }
 
+pub(crate) struct DevicePathIterator<'a>(Option<DevicePathNode<'a>>);
+
+impl<'a> DevicePathIterator<'a> {
+    const fn new(node: DevicePathNode<'a>) -> Self {
+        if node.is_end() { Self(None) } else { Self(Some(node)) }
+    }
+}
+
+impl<'a> Iterator for DevicePathIterator<'a> {
+    type Item = DevicePathNode<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let cur_node = self.0?;
+
+        let next_node = unsafe { cur_node.next_node() };
+        self.0 = if next_node.is_end() { None } else { Some(next_node) };
+
+        Some(cur_node)
+    }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) struct DevicePathNode<'a> {
+    protocol: NonNull<r_efi::protocols::device_path::Protocol>,
+    phantom: PhantomData<&'a r_efi::protocols::device_path::Protocol>,
+}
+
+impl<'a> DevicePathNode<'a> {
+    pub(crate) const fn new(protocol: NonNull<r_efi::protocols::device_path::Protocol>) -> Self {
+        Self { protocol, phantom: PhantomData }
+    }
+
+    pub(crate) const fn length(&self) -> u16 {
+        let len = unsafe { (*self.protocol.as_ptr()).length };
+        u16::from_le_bytes(len)
+    }
+
+    pub(crate) const fn node_type(&self) -> u8 {
+        unsafe { (*self.protocol.as_ptr()).r#type }
+    }
+
+    pub(crate) const fn sub_type(&self) -> u8 {
+        unsafe { (*self.protocol.as_ptr()).sub_type }
+    }
+
+    pub(crate) fn data(&self) -> &[u8] {
+        let length: usize = self.length().into();
+
+        // Some nodes do not have any special data
+        if length > 4 {
+            let raw_ptr: *const u8 = self.protocol.as_ptr().cast();
+            let data = unsafe { raw_ptr.add(4) };
+            unsafe { crate::slice::from_raw_parts(data, length - 4) }
+        } else {
+            &[]
+        }
+    }
+
+    pub(crate) const fn is_end(&self) -> bool {
+        self.node_type() == r_efi::protocols::device_path::TYPE_END
+            && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_ENTIRE
+    }
+
+    #[expect(dead_code)]
+    pub(crate) const fn is_end_instance(&self) -> bool {
+        self.node_type() == r_efi::protocols::device_path::TYPE_END
+            && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_INSTANCE
+    }
+
+    pub(crate) unsafe fn next_node(&self) -> Self {
+        let node = unsafe {
+            self.protocol
+                .cast::<u8>()
+                .add(self.length().into())
+                .cast::<r_efi::protocols::device_path::Protocol>()
+        };
+        Self::new(node)
+    }
+
+    #[expect(dead_code)]
+    pub(crate) fn to_path(&'a self) -> BorrowedDevicePath<'a> {
+        BorrowedDevicePath::new(self.protocol)
+    }
+
+    pub(crate) fn to_text(&self) -> io::Result<OsString> {
+        device_node_to_text(self.protocol)
+    }
+}
+
+impl<'a> PartialEq for DevicePathNode<'a> {
+    fn eq(&self, other: &Self) -> bool {
+        let self_len = self.length();
+        let other_len = other.length();
+
+        self_len == other_len
+            && unsafe {
+                compiler_builtins::mem::memcmp(
+                    self.protocol.as_ptr().cast(),
+                    other.protocol.as_ptr().cast(),
+                    usize::from(self_len),
+                ) == 0
+            }
+    }
+}
+
+impl<'a> crate::fmt::Debug for DevicePathNode<'a> {
+    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
+        match self.to_text() {
+            Ok(p) => p.fmt(f),
+            Err(_) => f
+                .debug_struct("DevicePathNode")
+                .field("type", &self.node_type())
+                .field("sub_type", &self.sub_type())
+                .field("length", &self.length())
+                .field("specific_device_path_data", &self.data())
+                .finish(),
+        }
+    }
+}
+
 pub(crate) struct OwnedProtocol<T> {
     guid: r_efi::efi::Guid,
     handle: NonNull<crate::ffi::c_void>,
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 3a238d160cb..91f55fcd32b 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -484,7 +484,12 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
-#[cfg(any(target_os = "redox", target_os = "rtems"))]
+#[cfg(target_os = "redox")]
+pub fn current_exe() -> io::Result<PathBuf> {
+    crate::fs::read_to_string("/scheme/sys/exe").map(PathBuf::from)
+}
+
+#[cfg(target_os = "rtems")]
 pub fn current_exe() -> io::Result<PathBuf> {
     crate::fs::read_to_string("sys:exe").map(PathBuf::from)
 }
diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs
index 0ea9db211b3..dd41921f263 100644
--- a/library/std/src/sys/pal/unix/process/process_common.rs
+++ b/library/std/src/sys/pal/unix/process/process_common.rs
@@ -19,8 +19,6 @@ use crate::{fmt, io, ptr};
 cfg_if::cfg_if! {
     if #[cfg(target_os = "fuchsia")] {
         // fuchsia doesn't have /dev/null
-    } else if #[cfg(target_os = "redox")] {
-        const DEV_NULL: &CStr = c"null:";
     } else if #[cfg(target_os = "vxworks")] {
         const DEV_NULL: &CStr = c"/null";
     } else {
diff --git a/library/std/src/sys/path/unix.rs b/library/std/src/sys/path/unix.rs
index 361e99964f1..faa2616a632 100644
--- a/library/std/src/sys/path/unix.rs
+++ b/library/std/src/sys/path/unix.rs
@@ -62,10 +62,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
 }
 
 pub(crate) fn is_absolute(path: &Path) -> bool {
-    if cfg!(target_os = "redox") {
-        // FIXME: Allow Redox prefixes
-        path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice())
-    } else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) {
+    if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) {
         path.has_root()
     } else {
         path.has_root() && path.prefix().is_some()
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 20084a65b8a..7c83c53d2c2 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -67,7 +67,7 @@ impl Std {
         self
     }
 
-    #[allow(clippy::wrong_self_convention)]
+    #[expect(clippy::wrong_self_convention)]
     pub fn is_for_mir_opt_tests(mut self, is_for_mir_opt_tests: bool) -> Self {
         self.is_for_mir_opt_tests = is_for_mir_opt_tests;
         self
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index c393eb55c62..2354fe1ebaf 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -2481,7 +2481,7 @@ impl Step for Gcc {
     fn run(self, builder: &Builder<'_>) -> Self::Output {
         let tarball = Tarball::new(builder, "gcc", &self.target.triple);
         let output = builder.ensure(super::gcc::Gcc { target: self.target });
-        tarball.add_file(output.libgccjit, ".", 0o644);
+        tarball.add_file(output.libgccjit, "lib", 0o644);
         tarball.generate()
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index 5a4bc9bdbcb..0aa2a332531 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -63,11 +63,7 @@ impl Step for Gcc {
         }
 
         build_gcc(&metadata, builder, target);
-
-        let lib_alias = metadata.install_dir.join("lib/libgccjit.so.0");
-        if !lib_alias.exists() {
-            t!(builder.symlink_file(&libgccjit_path, lib_alias));
-        }
+        create_lib_alias(builder, &libgccjit_path);
 
         t!(metadata.stamp.write());
 
@@ -75,6 +71,15 @@ impl Step for Gcc {
     }
 }
 
+/// Creates a libgccjit.so.0 alias next to libgccjit.so if it does not
+/// already exist
+fn create_lib_alias(builder: &Builder<'_>, libgccjit: &PathBuf) {
+    let lib_alias = libgccjit.parent().unwrap().join("libgccjit.so.0");
+    if !lib_alias.exists() {
+        t!(builder.symlink_file(libgccjit, lib_alias));
+    }
+}
+
 pub struct Meta {
     stamp: BuildStamp,
     out_dir: PathBuf,
@@ -109,8 +114,10 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<Pa
         builder.config.download_ci_gcc(&sha, &root);
         t!(gcc_stamp.write());
     }
-    // FIXME: put libgccjit.so into a lib directory in dist::Gcc
-    Some(root.join("libgccjit.so"))
+
+    let libgccjit = root.join("lib").join("libgccjit.so");
+    create_lib_alias(builder, &libgccjit);
+    Some(libgccjit)
 }
 
 #[cfg(test)]
@@ -177,6 +184,14 @@ fn libgccjit_built_path(install_dir: &Path) -> PathBuf {
 }
 
 fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
+    if builder.build.cc_tool(target).is_like_clang()
+        || builder.build.cxx_tool(target).is_like_clang()
+    {
+        panic!(
+            "Attempting to build GCC using Clang, which is known to misbehave. Please use GCC as the host C/C++ compiler. "
+        );
+    }
+
     let Meta { stamp: _, out_dir, install_dir, root } = metadata;
 
     t!(fs::create_dir_all(out_dir));
@@ -203,18 +218,13 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
     let mut configure_cmd = command(src_dir.join("configure"));
     configure_cmd
         .current_dir(out_dir)
-        // On CI, we compile GCC with Clang.
-        // The -Wno-everything flag is needed to make GCC compile with Clang 19.
-        // `-g -O2` are the default flags that are otherwise used by Make.
-        // FIXME(kobzol): change the flags once we have [gcc] configuration in config.toml.
-        .env("CXXFLAGS", "-Wno-everything -g -O2")
-        .env("CFLAGS", "-Wno-everything -g -O2")
         .arg("--enable-host-shared")
-        .arg("--enable-languages=jit")
+        .arg("--enable-languages=c,jit,lto")
         .arg("--enable-checking=release")
         .arg("--disable-bootstrap")
         .arg("--disable-multilib")
         .arg(format!("--prefix={}", install_dir.display()));
+
     let cc = builder.build.cc(target).display().to_string();
     let cc = builder
         .build
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index e198a8dd6a5..45f9f52cb82 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -582,10 +582,12 @@ Select which editor you would like to set up [default: None]: ";
             EditorKind::Emacs => &[
                 "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
                 "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
+                "b5dd299b93dca3ceeb9b335f929293cb3d4bf4977866fbe7ceeac2a8a9f99088",
             ],
             EditorKind::Helix => &[
                 "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233",
                 "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040",
+                "f252dcc30ca85a193a699581e5e929d5bd6c19d40d7a7ade5e257a9517a124a5",
             ],
             EditorKind::Vim | EditorKind::VsCode => &[
                 "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
@@ -598,10 +600,12 @@ Select which editor you would like to set up [default: None]: ";
                 "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d",
                 "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
                 "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d",
+                "e53e9129ca5ee5dcbd6ec8b68c2d87376474eb154992deba3c6d9ab1703e0717",
+            ],
+            EditorKind::Zed => &[
+                "bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c",
+                "a5380cf5dd9328731aecc5dfb240d16dac46ed272126b9728006151ef42f5909",
             ],
-            EditorKind::Zed => {
-                &["bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c"]
-            }
         }
     }
 
diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs
index ba9b1b2fc33..6a6731cafc5 100644
--- a/src/bootstrap/src/core/build_steps/suggest.rs
+++ b/src/bootstrap/src/core/build_steps/suggest.rs
@@ -1,7 +1,5 @@
 //! Attempt to magically identify good tests to run
 
-#![cfg_attr(feature = "build-metrics", allow(unused))]
-
 use std::path::PathBuf;
 use std::str::FromStr;
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index e80f8f9a4b7..cff286e99fa 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1908,8 +1908,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
                 llvm_components_passed = true;
             }
             if !builder.is_rust_llvm(target) {
-                // FIXME: missing Rust patches is not the same as being system llvm; we should rename the flag at some point.
-                // Inspecting the tests with `// no-system-llvm` in src/test *looks* like this is doing the right thing, though.
                 cmd.arg("--system-llvm");
             }
 
@@ -3377,7 +3375,7 @@ impl Step for CodegenCranelift {
         /*
         let mut prepare_cargo = build_cargo();
         prepare_cargo.arg("--").arg("prepare").arg("--download-dir").arg(&download_dir);
-        #[allow(deprecated)]
+        #[expect(deprecated)]
         builder.config.try_run(&mut prepare_cargo.into()).unwrap();
         */
 
@@ -3508,7 +3506,7 @@ impl Step for CodegenGCC {
         /*
         let mut prepare_cargo = build_cargo();
         prepare_cargo.arg("--").arg("prepare");
-        #[allow(deprecated)]
+        #[expect(deprecated)]
         builder.config.try_run(&mut prepare_cargo.into()).unwrap();
         */
 
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 016f09cb2a8..aaf6712102c 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -209,7 +209,7 @@ impl Step for ToolBuild {
     }
 }
 
-#[allow(clippy::too_many_arguments)] // FIXME: reduce the number of args and remove this.
+#[expect(clippy::too_many_arguments)] // FIXME: reduce the number of args and remove this.
 pub fn prepare_tool_cargo(
     builder: &Builder<'_>,
     compiler: Compiler,
@@ -1024,7 +1024,7 @@ pub struct LibcxxVersionTool {
     pub target: TargetSelection,
 }
 
-#[allow(dead_code)]
+#[expect(dead_code)]
 #[derive(Debug, Clone)]
 pub enum LibcxxVersion {
     Gnu(usize),
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 0b49751f73c..0b6b8513cc3 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1285,7 +1285,6 @@ impl<'a> Builder<'a> {
         host: TargetSelection,
         target: TargetSelection,
     ) -> Compiler {
-        #![allow(clippy::let_and_return)]
         let mut resolved_compiler = if self.build.force_use_stage2(stage) {
             trace!(target: "COMPILER_FOR", ?stage, "force_use_stage2");
             self.compiler(2, self.config.build)
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 9f09dd13f29..179e15e778b 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -1,4 +1,4 @@
-#[allow(clippy::module_inception)]
+#[expect(clippy::module_inception)]
 mod config;
 pub mod flags;
 #[cfg(test)]
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 95feb41ffd0..98eff664a5b 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -19,7 +19,7 @@ static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
 
 /// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet.
 fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> {
-    #[allow(deprecated)]
+    #[expect(deprecated)]
     config.try_run(cmd)
 }
 
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index fc408437838..91574f8bf5d 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -27,6 +27,7 @@ use std::{env, fs, io, str};
 
 use build_helper::ci::gha;
 use build_helper::exit;
+use cc::Tool;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
 use utils::build_stamp::BuildStamp;
 use utils::channel::GitInfo;
@@ -74,7 +75,7 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
 
 /// Extra `--check-cfg` to add when building the compiler or tools
 /// (Mode restriction, config name, config values (if any))
-#[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
+#[expect(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
 const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (None, "bootstrap", None),
     (Some(Mode::Rustc), "llvm_enzyme", None),
@@ -1218,6 +1219,16 @@ Executed at: {executed_at}"#,
         self.cc.borrow()[&target].path().into()
     }
 
+    /// Returns the internal `cc::Tool` for the C compiler.
+    fn cc_tool(&self, target: TargetSelection) -> Tool {
+        self.cc.borrow()[&target].clone()
+    }
+
+    /// Returns the internal `cc::Tool` for the C++ compiler.
+    fn cxx_tool(&self, target: TargetSelection) -> Tool {
+        self.cxx.borrow()[&target].clone()
+    }
+
     /// Returns C flags that `cc-rs` thinks should be enabled for the
     /// specified target by default.
     fn cc_handled_clags(&self, target: TargetSelection, c: CLang) -> Vec<String> {
diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs
index 7eb9ab96c8a..d07300e21d0 100644
--- a/src/bootstrap/src/utils/exec.rs
+++ b/src/bootstrap/src/utils/exec.rs
@@ -125,7 +125,7 @@ impl BootstrapCommand {
         Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self }
     }
 
-    #[allow(dead_code)]
+    #[expect(dead_code)]
     pub fn fail_fast(self) -> Self {
         Self { failure_behavior: BehaviorOnFailure::Exit, ..self }
     }
@@ -280,7 +280,7 @@ impl CommandOutput {
         !self.is_success()
     }
 
-    #[allow(dead_code)]
+    #[expect(dead_code)]
     pub fn status(&self) -> Option<ExitStatus> {
         match self.status {
             CommandStatus::Finished(status) => Some(status),
@@ -332,7 +332,6 @@ impl Default for CommandOutput {
 
 /// Helper trait to format both Command and BootstrapCommand as a short execution line,
 /// without all the other details (e.g. environment variables).
-#[allow(unused)]
 pub trait FormatShortCmd {
     fn format_short_cmd(&self) -> String;
 }
diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs
index 57766fd63fb..885fff9c32c 100644
--- a/src/bootstrap/src/utils/metrics.rs
+++ b/src/bootstrap/src/utils/metrics.rs
@@ -76,7 +76,7 @@ impl BuildMetrics {
 
         // Consider all the stats gathered so far as the parent's.
         if !state.running_steps.is_empty() {
-            self.collect_stats(&mut *state);
+            self.collect_stats(&mut state);
         }
 
         state.system_info.refresh_cpu_usage();
@@ -102,7 +102,7 @@ impl BuildMetrics {
 
         let mut state = self.state.borrow_mut();
 
-        self.collect_stats(&mut *state);
+        self.collect_stats(&mut state);
 
         let step = state.running_steps.pop().unwrap();
         if state.running_steps.is_empty() {
@@ -224,6 +224,7 @@ impl BuildMetrics {
         t!(serde_json::to_writer(&mut file, &json));
     }
 
+    #[expect(clippy::only_used_in_recursion)]
     fn prepare_json_step(&self, step: StepMetrics) -> JsonNode {
         let mut children = Vec::new();
         children.extend(step.children.into_iter().map(|child| self.prepare_json_step(child)));
diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs
index 45a188fb234..0de8b740227 100644
--- a/src/ci/citool/src/jobs.rs
+++ b/src/ci/citool/src/jobs.rs
@@ -24,6 +24,8 @@ pub struct Job {
     /// Free additional disk space in the job, by removing unused packages.
     #[serde(default)]
     pub free_disk: Option<bool>,
+    /// Documentation link to a resource that could help people debug this CI job.
+    pub doc_url: Option<String>,
 }
 
 impl Job {
@@ -103,6 +105,8 @@ struct GithubActionsJob {
     continue_on_error: Option<bool>,
     #[serde(skip_serializing_if = "Option::is_none")]
     free_disk: Option<bool>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    doc_url: Option<String>,
 }
 
 /// Skip CI jobs that are not supposed to be executed on the given `channel`.
@@ -188,6 +192,7 @@ fn calculate_jobs(
                 env,
                 continue_on_error: job.continue_on_error,
                 free_disk: job.free_disk,
+                doc_url: job.doc_url,
             }
         })
         .collect();
diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs
index 17e42d49286..62daa2e6853 100644
--- a/src/ci/citool/src/merge_report.rs
+++ b/src/ci/citool/src/merge_report.rs
@@ -1,8 +1,8 @@
-use std::cmp::Reverse;
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
+use std::path::PathBuf;
 
 use anyhow::Context;
-use build_helper::metrics::{JsonRoot, TestOutcome};
+use build_helper::metrics::{JsonRoot, TestOutcome, TestSuiteMetadata};
 
 use crate::jobs::JobDatabase;
 use crate::metrics::get_test_suites;
@@ -13,8 +13,10 @@ type JobName = String;
 /// Computes a post merge CI analysis report between the `parent` and `current` commits.
 pub fn post_merge_report(job_db: JobDatabase, parent: Sha, current: Sha) -> anyhow::Result<()> {
     let jobs = download_all_metrics(&job_db, &parent, &current)?;
-    let diffs = aggregate_test_diffs(&jobs)?;
-    report_test_changes(diffs);
+    let aggregated_test_diffs = aggregate_test_diffs(&jobs)?;
+
+    println!("Comparing {parent} (base) -> {current} (this PR)\n");
+    report_test_diffs(aggregated_test_diffs);
 
     Ok(())
 }
@@ -54,7 +56,16 @@ Maybe it was newly added?"#,
     Ok(jobs)
 }
 
+/// Downloads job metrics of the given job for the given commit.
+/// Caches the result on the local disk.
 fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> {
+    let cache_path = PathBuf::from(".citool-cache").join(sha).join(job_name).join("metrics.json");
+    if let Some(cache_entry) =
+        std::fs::read_to_string(&cache_path).ok().and_then(|data| serde_json::from_str(&data).ok())
+    {
+        return Ok(cache_entry);
+    }
+
     let url = get_metrics_url(job_name, sha);
     let mut response = ureq::get(&url).call()?;
     if !response.status().is_success() {
@@ -68,6 +79,13 @@ fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> {
         .body_mut()
         .read_json()
         .with_context(|| anyhow::anyhow!("cannot deserialize metrics from {url}"))?;
+
+    // Ignore errors if cache cannot be created
+    if std::fs::create_dir_all(cache_path.parent().unwrap()).is_ok() {
+        if let Ok(serialized) = serde_json::to_string(&data) {
+            let _ = std::fs::write(&cache_path, &serialized);
+        }
+    }
     Ok(data)
 }
 
@@ -76,81 +94,80 @@ fn get_metrics_url(job_name: &str, sha: &str) -> String {
     format!("https://ci-artifacts.rust-lang.org/rustc-builds{suffix}/{sha}/metrics-{job_name}.json")
 }
 
+/// Represents a difference in the outcome of tests between a base and a current commit.
+/// Maps test diffs to jobs that contained them.
+#[derive(Debug)]
+struct AggregatedTestDiffs {
+    diffs: HashMap<TestDiff, Vec<JobName>>,
+}
+
 fn aggregate_test_diffs(
     jobs: &HashMap<JobName, JobMetrics>,
-) -> anyhow::Result<Vec<AggregatedTestDiffs>> {
-    let mut job_diffs = vec![];
+) -> anyhow::Result<AggregatedTestDiffs> {
+    let mut diffs: HashMap<TestDiff, Vec<JobName>> = HashMap::new();
 
     // Aggregate test suites
     for (name, metrics) in jobs {
         if let Some(parent) = &metrics.parent {
             let tests_parent = aggregate_tests(parent);
             let tests_current = aggregate_tests(&metrics.current);
-            let test_diffs = calculate_test_diffs(tests_parent, tests_current);
-            if !test_diffs.is_empty() {
-                job_diffs.push((name.clone(), test_diffs));
+            for diff in calculate_test_diffs(tests_parent, tests_current) {
+                diffs.entry(diff).or_default().push(name.to_string());
             }
         }
     }
 
-    // Aggregate jobs with the same diff, as often the same diff will appear in many jobs
-    let job_diffs: HashMap<Vec<(Test, TestOutcomeDiff)>, Vec<String>> =
-        job_diffs.into_iter().fold(HashMap::new(), |mut acc, (job, diffs)| {
-            acc.entry(diffs).or_default().push(job);
-            acc
-        });
+    Ok(AggregatedTestDiffs { diffs })
+}
 
-    Ok(job_diffs
-        .into_iter()
-        .map(|(test_diffs, jobs)| AggregatedTestDiffs { jobs, test_diffs })
-        .collect())
+#[derive(Eq, PartialEq, Hash, Debug)]
+enum TestOutcomeDiff {
+    ChangeOutcome { before: TestOutcome, after: TestOutcome },
+    Missing { before: TestOutcome },
+    Added(TestOutcome),
 }
 
-fn calculate_test_diffs(
-    reference: TestSuiteData,
-    current: TestSuiteData,
-) -> Vec<(Test, TestOutcomeDiff)> {
-    let mut diffs = vec![];
+#[derive(Eq, PartialEq, Hash, Debug)]
+struct TestDiff {
+    test: Test,
+    diff: TestOutcomeDiff,
+}
+
+fn calculate_test_diffs(parent: TestSuiteData, current: TestSuiteData) -> HashSet<TestDiff> {
+    let mut diffs = HashSet::new();
     for (test, outcome) in &current.tests {
-        match reference.tests.get(test) {
+        match parent.tests.get(test) {
             Some(before) => {
                 if before != outcome {
-                    diffs.push((
-                        test.clone(),
-                        TestOutcomeDiff::ChangeOutcome {
+                    diffs.insert(TestDiff {
+                        test: test.clone(),
+                        diff: TestOutcomeDiff::ChangeOutcome {
                             before: before.clone(),
                             after: outcome.clone(),
                         },
-                    ));
+                    });
                 }
             }
-            None => diffs.push((test.clone(), TestOutcomeDiff::Added(outcome.clone()))),
+            None => {
+                diffs.insert(TestDiff {
+                    test: test.clone(),
+                    diff: TestOutcomeDiff::Added(outcome.clone()),
+                });
+            }
         }
     }
-    for (test, outcome) in &reference.tests {
+    for (test, outcome) in &parent.tests {
         if !current.tests.contains_key(test) {
-            diffs.push((test.clone(), TestOutcomeDiff::Missing { before: outcome.clone() }));
+            diffs.insert(TestDiff {
+                test: test.clone(),
+                diff: TestOutcomeDiff::Missing { before: outcome.clone() },
+            });
         }
     }
 
     diffs
 }
 
-/// Represents a difference in the outcome of tests between a base and a current commit.
-#[derive(Debug)]
-struct AggregatedTestDiffs {
-    /// All jobs that had the exact same test diffs.
-    jobs: Vec<String>,
-    test_diffs: Vec<(Test, TestOutcomeDiff)>,
-}
-
-#[derive(Eq, PartialEq, Hash, Debug)]
-enum TestOutcomeDiff {
-    ChangeOutcome { before: TestOutcome, after: TestOutcome },
-    Missing { before: TestOutcome },
-    Added(TestOutcome),
-}
-
 /// Aggregates test suite executions from all bootstrap invocations in a given CI job.
 #[derive(Default)]
 struct TestSuiteData {
@@ -160,6 +177,7 @@ struct TestSuiteData {
 #[derive(Hash, PartialEq, Eq, Debug, Clone)]
 struct Test {
     name: String,
+    is_doctest: bool,
 }
 
 /// Extracts all tests from the passed metrics and map them to their outcomes.
@@ -168,7 +186,10 @@ fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData {
     let test_suites = get_test_suites(&metrics);
     for suite in test_suites {
         for test in &suite.tests {
-            let test_entry = Test { name: normalize_test_name(&test.name) };
+            // Poor man's detection of doctests based on the "(line XYZ)" suffix
+            let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. })
+                && test.name.contains("(line");
+            let test_entry = Test { name: normalize_test_name(&test.name), is_doctest };
             tests.insert(test_entry, test.outcome.clone());
         }
     }
@@ -181,16 +202,13 @@ fn normalize_test_name(name: &str) -> String {
 }
 
 /// Prints test changes in Markdown format to stdout.
-fn report_test_changes(mut diffs: Vec<AggregatedTestDiffs>) {
+fn report_test_diffs(diff: AggregatedTestDiffs) {
     println!("## Test differences");
-    if diffs.is_empty() {
+    if diff.diffs.is_empty() {
         println!("No test diffs found");
         return;
     }
 
-    // Sort diffs in decreasing order by diff count
-    diffs.sort_by_key(|entry| Reverse(entry.test_diffs.len()));
-
     fn format_outcome(outcome: &TestOutcome) -> String {
         match outcome {
             TestOutcome::Passed => "pass".to_string(),
@@ -219,36 +237,79 @@ fn report_test_changes(mut diffs: Vec<AggregatedTestDiffs>) {
         }
     }
 
-    let max_diff_count = 10;
-    let max_job_count = 5;
-    let max_test_count = 10;
-
-    for diff in diffs.iter().take(max_diff_count) {
-        let mut jobs = diff.jobs.clone();
-        jobs.sort();
-
-        let jobs = jobs.iter().take(max_job_count).map(|j| format!("`{j}`")).collect::<Vec<_>>();
+    fn format_job_group(group: u64) -> String {
+        format!("**J{group}**")
+    }
 
-        let extra_jobs = diff.jobs.len().saturating_sub(max_job_count);
-        let suffix = if extra_jobs > 0 {
-            format!(" (and {extra_jobs} {})", pluralize("other", extra_jobs))
-        } else {
-            String::new()
+    // It would be quite noisy to repeat the jobs that contained the test changes after/next to
+    // every test diff. At the same time, grouping the test diffs by
+    // [unique set of jobs that contained them] also doesn't work well, because the test diffs
+    // would have to be duplicated several times.
+    // Instead, we create a set of unique job groups, and then print a job group after each test.
+    // We then print the job groups at the end, as a sort of index.
+    let mut grouped_diffs: Vec<(&TestDiff, u64)> = vec![];
+    let mut job_list_to_group: HashMap<&[JobName], u64> = HashMap::new();
+    let mut job_index: Vec<&[JobName]> = vec![];
+
+    let original_diff_count = diff.diffs.len();
+    let diffs = diff
+        .diffs
+        .into_iter()
+        .filter(|(diff, _)| !diff.test.is_doctest)
+        .map(|(diff, mut jobs)| {
+            jobs.sort();
+            (diff, jobs)
+        })
+        .collect::<Vec<_>>();
+    let doctest_count = original_diff_count.saturating_sub(diffs.len());
+
+    let max_diff_count = 100;
+    for (diff, jobs) in diffs.iter().take(max_diff_count) {
+        let jobs = &*jobs;
+        let job_group = match job_list_to_group.get(jobs.as_slice()) {
+            Some(id) => *id,
+            None => {
+                let id = job_index.len() as u64;
+                job_index.push(jobs);
+                job_list_to_group.insert(jobs, id);
+                id
+            }
         };
-        println!("- {}{suffix}", jobs.join(","));
+        grouped_diffs.push((diff, job_group));
+    }
 
-        let extra_tests = diff.test_diffs.len().saturating_sub(max_test_count);
-        for (test, outcome_diff) in diff.test_diffs.iter().take(max_test_count) {
-            println!("  - {}: {}", test.name, format_diff(&outcome_diff));
-        }
-        if extra_tests > 0 {
-            println!("  - (and {extra_tests} additional {})", pluralize("tests", extra_tests));
-        }
+    // Sort diffs by job group and test name
+    grouped_diffs.sort_by(|(d1, g1), (d2, g2)| g1.cmp(&g2).then(d1.test.name.cmp(&d2.test.name)));
+
+    for (diff, job_group) in grouped_diffs {
+        println!(
+            "- `{}`: {} ({})",
+            diff.test.name,
+            format_diff(&diff.diff),
+            format_job_group(job_group)
+        );
     }
 
     let extra_diffs = diffs.len().saturating_sub(max_diff_count);
     if extra_diffs > 0 {
-        println!("\n(and {extra_diffs} additional {})", pluralize("diff", extra_diffs));
+        println!("\n(and {extra_diffs} additional {})", pluralize("test diff", extra_diffs));
+    }
+
+    if doctest_count > 0 {
+        println!(
+            "\nAdditionally, {doctest_count} doctest {} were found. These are ignored, as they are noisy.",
+            pluralize("diff", doctest_count)
+        );
+    }
+
+    // Now print the job group index
+    println!("\n**Job group index**\n");
+    for (group, jobs) in job_index.into_iter().enumerate() {
+        println!(
+            "- {}: {}",
+            format_job_group(group as u64),
+            jobs.iter().map(|j| format!("`{j}`")).collect::<Vec<_>>().join(", ")
+        );
     }
 }
 
diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs
index 1d81d58f893..788f5e7e4f6 100644
--- a/src/ci/citool/tests/jobs.rs
+++ b/src/ci/citool/tests/jobs.rs
@@ -40,7 +40,7 @@ try-job: dist-i686-msvc"#,
 fn pr_jobs() {
     let stdout = get_matrix("pull_request", "commit", "refs/heads/pr/1234");
     insta::assert_snapshot!(stdout, @r#"
-    jobs=[{"name":"mingw-check","full_name":"PR - mingw-check","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true}]
+    jobs=[{"name":"mingw-check","full_name":"PR - mingw-check","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true,"doc_url":"https://foo.bar"}]
     run_type=pr
     "#);
 }
diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml
index 56b9ced2071..ff4d1772f59 100644
--- a/src/ci/citool/tests/test-jobs.yml
+++ b/src/ci/citool/tests/test-jobs.yml
@@ -75,6 +75,7 @@ pr:
     <<: *job-linux-4c
   - name: mingw-check-tidy
     continue_on_error: true
+    doc_url: https://foo.bar
     <<: *job-linux-4c
 
 # Jobs that run when you perform a try build (@bors try)
diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
index eb39861d8c7..cf030f6830e 100644
--- a/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile
@@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1
-ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 
 # llvm.use-linker conflicts with downloading CI LLVM
 ENV NO_DOWNLOAD_CI_LLVM 1
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index f54ecef1e30..ae5bf8946dd 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -101,7 +101,9 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
     ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
     --host $HOSTS --target $HOSTS \
     --include-default-paths \
-    build-manifest bootstrap gcc
+    build-manifest bootstrap && \
+    # Use GCC for building GCC, as it seems to behave badly when built with Clang
+    CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc
 ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
 
 # This is the only builder which will create source tarballs
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 9234c6dc921..b32fa6c8e4e 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -41,8 +41,6 @@ COPY host-x86_64/mingw-check/check-default-config-profiles.sh /scripts/
 COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
-ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
-
 # Check library crates on all tier 1 targets.
 # We disable optimized compiler built-ins because that requires a C toolchain for the target.
 # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs.
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
index 292dbfd20a5..b97568b0819 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
@@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV RUSTBUILD_FORCE_CLANG_BASED_TESTS 1
-ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
 
 # llvm.use-linker conflicts with downloading CI LLVM
 ENV NO_DOWNLOAD_CI_LLVM 1
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 6658b83efc8..2805bb1118d 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -361,6 +361,7 @@ docker \
   --env TOOLSTATE_PUBLISH \
   --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \
   --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \
+  --env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \
   --env BASE_COMMIT="$BASE_COMMIT" \
   --env DIST_TRY_BUILD \
   --env PR_CI_JOB \
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index eba55338ff8..d8c3625af28 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -267,11 +267,13 @@ auto:
     # nightly features to compile, and this job would fail if
     # executed on beta and stable.
     only_on_channel: nightly
+    doc_url: https://rustc-dev-guide.rust-lang.org/tests/fuchsia.html
     <<: *job-linux-8c
 
   # Tests integration with Rust for Linux.
   # Builds stage 1 compiler and tries to compile a few RfL examples with it.
   - name: x86_64-rust-for-linux
+    doc_url: https://rustc-dev-guide.rust-lang.org/tests/rust-for-linux.html
     <<: *job-linux-4c
 
   - name: x86_64-gnu
diff --git a/src/ci/run.sh b/src/ci/run.sh
index b874f71832d..54fbf8b6912 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -6,6 +6,10 @@ if [ -n "$CI_JOB_NAME" ]; then
   echo "[CI_JOB_NAME=$CI_JOB_NAME]"
 fi
 
+if [ -n "$CI_JOB_DOC_URL" ]; then
+  echo "[CI_JOB_DOC_URL=$CI_JOB_DOC_URL]"
+fi
+
 if [ "$NO_CHANGE_USER" = "" ]; then
   if [ "$LOCAL_USER_ID" != "" ]; then
     id -u user &>/dev/null || useradd --shell /bin/bash -u $LOCAL_USER_ID -o -c "" -m user
@@ -54,13 +58,8 @@ if [ "$FORCE_CI_RUSTC" == "" ]; then
     DISABLE_CI_RUSTC_IF_INCOMPATIBLE=1
 fi
 
-if ! isCI || isCiBranch auto || isCiBranch beta || isCiBranch try || isCiBranch try-perf || \
-  isCiBranch automation/bors/try; then
-    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings --enable-verbose-tests"
-    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.metrics"
-    HAS_METRICS=1
-fi
-
+RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings --enable-verbose-tests"
+RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.metrics"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-verbose-configure"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules"
@@ -261,23 +260,6 @@ else
   do_make "$RUST_CHECK_TARGET"
 fi
 
-if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then
-  rm -f config.toml
-  $SRC/configure --set change-id=99999999
-
-  # Save the build metrics before we wipe the directory
-  if [ "$HAS_METRICS" = 1 ]; then
-    mv build/metrics.json .
-  fi
-  rm -rf build
-  if [ "$HAS_METRICS" = 1 ]; then
-    mkdir build
-    mv metrics.json build
-  fi
-
-  CARGO_INCREMENTAL=0 ../x check
-fi
-
 echo "::group::sccache stats"
 sccache --show-stats || true
 echo "::endgroup::"
diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md
index 2464ffbbc50..6a25a91f56a 100644
--- a/src/doc/rustc-dev-guide/README.md
+++ b/src/doc/rustc-dev-guide/README.md
@@ -82,6 +82,7 @@ cargo +stable install josh-proxy --git https://github.com/josh-project/josh --ta
 Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version.
 
 ### Pull changes from `rust-lang/rust` into this repository
+
 1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide`
 2) Run the pull command
     ```
@@ -95,3 +96,15 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im
     $ cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username>
     ```
 2) Create a PR from `<branch-name>` into `rust-lang/rust`
+
+#### Minimal git config
+
+For simplicity (ease of implementation purposes), the josh-sync script simply calls out to system git. This means that the git invocation may be influenced by global (or local) git configuration.
+
+You may observe "Nothing to pull" even if you *know* rustc-pull has something to pull if your global git config sets `fetch.prunetags = true` (and possibly other configurations may cause unexpected outcomes).
+
+To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g.
+
+```
+$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull
+```
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index ce21bb8ef39..eb779d9ab05 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-4ecd70ddd1039a3954056c1071e40278048476fa
+8536f201ffdb2c24925d7f9e87996d7dca93428b
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 106db508ebb..ce74c741b39 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -178,7 +178,7 @@
         - [Inference details](./opaque-types-impl-trait-inference.md)
         - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
         - [Region inference restrictions][opaque-infer]
-- [Effect checking](./effects.md)
+- [Const condition checking](./effects.md)
 - [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md)
 - [Unsafety Checking](./unsafety-checking.md)
 - [MIR dataflow](./mir/dataflow.md)
diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
index 92d4ce32f92..0b45956b160 100644
--- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
+++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md
@@ -116,14 +116,14 @@ so let's go through each in detail.
    at the time of the branch,
    and the remaining part is the current date.
 
-2. Apply Rust-specific patches to the llvm-project repository.
+1. Apply Rust-specific patches to the llvm-project repository.
    All features and bugfixes are upstream,
    but there's often some weird build-related patches
    that don't make sense to upstream.
    These patches are typically the latest patches in the
    rust-lang/llvm-project branch that rustc is currently using.
 
-3. Build the new LLVM in the `rust` repository.
+1. Build the new LLVM in the `rust` repository.
    To do this,
    you'll want to update the `src/llvm-project` repository to your branch,
    and the revision you've created.
@@ -151,7 +151,7 @@ so let's go through each in detail.
    download-ci-llvm = false
    ```
 
-4. Test for regressions across other platforms. LLVM often has at least one bug
+1. Test for regressions across other platforms. LLVM often has at least one bug
    for non-tier-1 architectures, so it's good to do some more testing before
    sending this to bors! If you're low on resources you can send the PR as-is
    now to bors, though, and it'll get tested anyway.
@@ -170,22 +170,17 @@ so let's go through each in detail.
    * `./src/ci/docker/run.sh dist-various-2`
    * `./src/ci/docker/run.sh armhf-gnu`
 
-5. Prepare a PR to `rust-lang/rust`. Work with maintainers of
+1. Prepare a PR to `rust-lang/rust`. Work with maintainers of
    `rust-lang/llvm-project` to get your commit in a branch of that repository,
    and then you can send a PR to `rust-lang/rust`. You'll change at least
    `src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
 
-   <!-- date-check: Sep 2024 -->
+   <!-- date-check: mar 2025 -->
    > For prior art, here are some previous LLVM updates:
-   > - [LLVM 11](https://github.com/rust-lang/rust/pull/73526)
-   > - [LLVM 12](https://github.com/rust-lang/rust/pull/81451)
-   > - [LLVM 13](https://github.com/rust-lang/rust/pull/87570)
-   > - [LLVM 14](https://github.com/rust-lang/rust/pull/93577)
-   > - [LLVM 15](https://github.com/rust-lang/rust/pull/99464)
-   > - [LLVM 16](https://github.com/rust-lang/rust/pull/109474)
    > - [LLVM 17](https://github.com/rust-lang/rust/pull/115959)
    > - [LLVM 18](https://github.com/rust-lang/rust/pull/120055)
    > - [LLVM 19](https://github.com/rust-lang/rust/pull/127513)
+   > - [LLVM 20](https://github.com/rust-lang/rust/pull/135763)
 
    Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR
    before actually updating `src/llvm-project`.
@@ -194,7 +189,7 @@ so let's go through each in detail.
    others interested in trying out the new LLVM can benefit from work you've done
    to update the C++ bindings.
 
-3. Over the next few months,
+1. Over the next few months,
    LLVM will continually push commits to its `release/a.b` branch.
    We will often want to have those bug fixes as well.
    The merge process for that is to use `git merge` itself to merge LLVM's
@@ -202,9 +197,9 @@ so let's go through each in detail.
    This is typically
    done multiple times when necessary while LLVM's release branch is baking.
 
-4. LLVM then announces the release of version `a.b`.
+1. LLVM then announces the release of version `a.b`.
 
-5. After LLVM's official release,
+1. After LLVM's official release,
    we follow the process of creating a new branch on the
    rust-lang/llvm-project repository again,
    this time with a new date.
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
index 24b9783ddf0..35d33ebdb0e 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md
@@ -129,7 +129,7 @@ Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need
 
 ```rs
 #[cfg(feature = "tracing")]
-use tracing::{instrument, trace};
+use tracing::instrument;
 
 struct Foo;
 
@@ -138,7 +138,6 @@ impl Step for Foo {
 
     #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))]
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        #[cfg(feature = "tracing")]
         trace!(?run, "entered Foo::should_run");
 
         todo!()
@@ -154,7 +153,6 @@ impl Step for Foo {
         ),
     )]
     fn run(self, builder: &Builder<'_>) -> Self::Output {
-        #[cfg(feature = "tracing")]
         trace!(?run, "entered Foo::run");
 
         todo!()
diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md
index cd215277e69..14d10d4a59d 100644
--- a/src/doc/rustc-dev-guide/src/building/new-target.md
+++ b/src/doc/rustc-dev-guide/src/building/new-target.md
@@ -4,12 +4,11 @@ These are a set of steps to add support for a new target. There are
 numerous end states and paths to get there, so not all sections may be
 relevant to your desired goal.
 
-See also the associated documentation in the
-[target tier policy][target_tier_policy_add].
+See also the associated documentation in the [target tier policy].
 
 <!-- toc -->
 
-[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
+[target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
 
 ## Specifying a new LLVM
 
diff --git a/src/doc/rustc-dev-guide/src/effects.md b/src/doc/rustc-dev-guide/src/effects.md
index 1fda7bcbb13..c7aa2714668 100644
--- a/src/doc/rustc-dev-guide/src/effects.md
+++ b/src/doc/rustc-dev-guide/src/effects.md
@@ -1,66 +1,159 @@
-# Effects and effect checking
-
-Note: all of this describes the implementation of the unstable `effects` and
-`const_trait_impl` features. None of this implementation is usable or visible from
-stable Rust.
-
-The implementation of const traits and `~const` bounds is a limited effect system.
-It is used to allow trait bounds on `const fn` to be used within the `const fn` for
-method calls. Within the function, in order to know whether a method on a trait
-bound is `const`, we need to know whether there is a `~const` bound for the trait.
-In order to know whether we can instantiate a `~const` bound on a `const fn`, we
-need to know whether there is a `const_trait` impl for the type and trait being
-used (or whether the `const fn` is used at runtime, then any type implementing the
-trait is ok, just like with other bounds).
-
-We perform these checks via a const generic boolean that gets attached to all
-`const fn` and `const trait`. The following sections will explain the desugarings
-and the way we perform the checks at call sites.
-
-The const generic boolean is inverted to the meaning of `const`. In the compiler
-it is called `host`, because it enables "host APIs" like `static` items, network
-access, disk access, random numbers and everything else that isn't available in
-`const` contexts. So `false` means "const", `true` means "not const" and if it's
-a generic parameter, it means "maybe const" (meaning we're in a const fn or const
-trait).
-
-## `const fn`
-
-All `const fn` have a `#[rustc_host] const host: bool` generic parameter that is
-hidden from users. Any `~const Trait` bounds in the generics list or `where` bounds
-of a `const fn` get converted to `Trait<host> + Trait<true>` bounds. The `Trait<true>`
-exists so that associated types of the generic param can be used from projections
-like `<T as Trait>::Assoc`, because there are no `<T as ~const Trait>` projections for now.
-
-## `#[const_trait] trait`s
-
-The `#[const_trait]` attribute gives the marked trait a `#[rustc_host] const host: bool`
-generic parameter. All functions of the trait "inherit" this generic parameter, just like
-they have all the regular generic parameters of the trait. Any `~const Trait` super-trait
-bounds get desugared to `Trait<host> + Trait<true>` in order to allow using associated
-types and consts of the super traits in the trait declaration. This is necessary, because
-`<Self as SuperTrait>::Assoc` is always `<Self as SuperTrait<true>>::Assoc` as there is
-no `<Self as ~const SuperTrait>` syntax.
-
-## `typeck` performing method and function call checks.
-
-When generic parameters are instantiated for any items, the `host` generic parameter
-is always instantiated as an inference variable. This is a special kind of inference var
-that is not part of the type or const inference variables, similar to how we have
-special inference variables for type variables that we know to be an integer, but not
-yet which one. These separate inference variables fall back to `true` at
-the end of typeck (in `fallback_effects`) to ensure that `let _ = some_fn_item_name;`
-will keep compiling.
-
-All actually used (in function calls, casts, or anywhere else) function items, will
-have the `enforce_context_effects` method invoked.
-It trivially returns if the function being called has no `host` generic parameter.
-
-In order to error if a non-const function is called in a const context, we have not
-yet disabled the const-check logic that happens on MIR, because
-`enforce_context_effects` does not yet perform this check.
-
-The function call's `host` parameter is then equated to the context's `host` value,
-which almost always trivially succeeds, as it was an inference var. If the inference
-var has already been bound (since the function item is invoked twice), the second
-invocation checks it against the first.
+# Effects and const condition checking
+
+## The `HostEffect` predicate
+
+[`HostEffectPredicate`]s are a kind of predicate from `~const Tr` or `const Tr`
+bounds. It has a trait reference, and a `constness` which could be `Maybe` or
+`Const` depending on the bound. Because `~const Tr`, or rather `Maybe` bounds
+apply differently based on whichever contexts they are in, they have different
+behavior than normal bounds. Where normal trait bounds on a function such as
+`T: Tr` are collected within the [`predicates_of`] query to be proven when a
+function is called and to be assumed within the function, bounds such as
+`T: ~const Tr` will behave as a normal trait bound and add `T: Tr` to the result
+from `predicates_of`, but also adds a `HostEffectPredicate` to the
+[`const_conditions`] query.
+
+On the other hand, `T: const Tr` bounds do not change meaning across contexts,
+therefore they will result in `HostEffect(T: Tr, const)` being added to
+`predicates_of`, and not `const_conditions`.
+
+[`HostEffectPredicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/predicate/struct.HostEffectPredicate.html
+[`predicates_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.predicates_of
+[`const_conditions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_conditions
+
+## The `const_conditions` query
+
+`predicates_of` represents a set of predicates that need to be proven to use an
+item. For example, to use `foo` in the example below:
+
+```rust
+fn foo<T>() where T: Default {}
+```
+
+We must be able to prove that `T` implements `Default`. In a similar vein,
+`const_conditions` represents a set of predicates that need to be proven to use
+an item *in const contexts*. If we adjust the example above to use `const` trait
+bounds:
+
+```rust
+const fn foo<T>() where T: ~const Default {}
+```
+
+Then `foo` would get a `HostEffect(T: Default, maybe)` in the `const_conditions`
+query, suggesting that in order to call `foo` from const contexts, one must
+prove that `T` has a const implementation of `Default`.
+
+## Enforcement of `const_conditions`
+
+`const_conditions` are currently checked in various places. 
+
+Every call in HIR from a const context (which includes `const fn` and `const`
+items) will check that `const_conditions` of the function we are calling hold.
+This is done in [`FnCtxt::enforce_context_effects`]. Note that we don't check
+if the function is only referred to but not called, as the following code needs
+to compile:
+
+```rust
+const fn hi<T: ~const Default>() -> T {
+    T::default()
+}
+const X: fn() -> u32 = hi::<u32>;
+```
+
+For a trait `impl` to be well-formed, we must be able to prove the
+`const_conditions` of the trait from the `impl`'s environment. This is checked
+in [`wfcheck::check_impl`].
+
+Here's an example:
+
+```rust
+#[const_trait]
+trait Bar {}
+#[const_trait]
+trait Foo: ~const Bar {}
+// `const_conditions` contains `HostEffect(Self: Bar, maybe)`
+
+impl const Bar for () {}
+impl const Foo for () {}
+// ^ here we check `const_conditions` for the impl to be well-formed
+```
+
+Methods of trait impls must not have stricter bounds than the method of the
+trait that they are implementing. To check that the methods are compatible, a
+hybrid environment is constructed with the predicates of the `impl` plus the
+predicates of the trait method, and we attempt to prove the predicates of the
+impl method. We do the same for `const_conditions`:
+
+```rust
+#[const_trait]
+trait Foo {
+    fn hi<T: ~const Default>();
+}
+
+impl<T: ~const Clone> Foo for Vec<T> {
+    fn hi<T: ~const PartialEq>();
+    // ^ we can't prove `T: ~const PartialEq` given `T: ~const Clone` and
+    // `T: ~const Default`, therefore we know that the method on the impl
+    // is stricter than the method on the trait.
+}
+```
+
+These checks are done in [`compare_method_predicate_entailment`]. A similar
+function that does the same check for associated types is called
+[`compare_type_predicate_entailment`]. Both of these need to consider
+`const_conditions` when in const contexts.
+
+In MIR, as part of const checking, `const_conditions` of items that are called
+are revalidated again in [`Checker::revalidate_conditional_constness`].
+
+[`compare_method_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
+[`compare_type_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_type_predicate_entailment.html
+[`FnCtxt::enforce_context_effects`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.enforce_context_effects
+[`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html
+[`Checker::revalidate_conditional_constness`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/check_consts/check/struct.Checker.html#method.revalidate_conditional_constness
+
+## `explicit_implied_const_bounds` on associated types and traits
+
+Bounds on associated types, opaque types, and supertraits such as
+```rust
+trait Foo: ~const PartialEq {
+    type X: ~const PartialEq;
+}
+
+fn foo() -> impl ~const PartialEq {
+    // ^ unimplemented syntax
+}
+```
+
+Have their bounds represented differently. Unlike `const_conditions` which need
+to be proved for callers, and can be assumed inside the definition (e.g. trait
+bounds on functions), these bounds need to be proved at definition (at the impl,
+or when returning the opaque) but can be assumed for callers. The non-const
+equivalent of these bounds are called [`explicit_item_bounds`].
+
+These bounds are checked in [`compare_impl_item::check_type_bounds`] for HIR
+typeck, [`evaluate_host_effect_from_item_bounds`] in the old solver and
+[`consider_additional_alias_assumptions`] in the new solver.
+
+[`explicit_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.explicit_item_bounds
+[`compare_impl_item::check_type_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.check_type_bounds.html
+[`evaluate_host_effect_from_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/effects/fn.evaluate_host_effect_from_item_bounds.html
+[`consider_additional_alias_assumptions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/trait.GoalKind.html#tymethod.consider_additional_alias_assumptions
+
+## Proving `HostEffectPredicate`s
+
+`HostEffectPredicate`s are implemented both in the [old solver] and the [new
+trait solver]. In general, we can prove a `HostEffect` predicate when either of
+these conditions are met:
+
+* The predicate can be assumed from caller bounds;
+* The type has a `const` `impl` for the trait, *and* that const conditions on
+the impl holds, *and* that the `explicit_implied_const_bounds` on the trait
+holds; or
+* The type has a built-in implementation for the trait in const contexts. For
+example, `Fn` may be implemented by function items if their const conditions
+are satisfied, or `Destruct` is implemented in const contexts if the type can
+be dropped at compile time.
+
+[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
+[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html
diff --git a/src/doc/rustc-dev-guide/src/solve/trait-solving.md b/src/doc/rustc-dev-guide/src/solve/trait-solving.md
index 345ee0b094e..c1eb1a94b96 100644
--- a/src/doc/rustc-dev-guide/src/solve/trait-solving.md
+++ b/src/doc/rustc-dev-guide/src/solve/trait-solving.md
@@ -2,8 +2,7 @@
 
 This chapter describes how trait solving works with the new WIP solver located in
 [`rustc_trait_selection/solve`][solve]. Feel free to also look at the docs for
-[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md)
-can be found separately.
+[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md).
 
 ## Core concepts
 
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 14f18a7ecf7..d5b896a8eee 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -119,8 +119,7 @@ for more details.
 These directives are used to ignore the test in some situations, which
 means the test won't be compiled or run.
 
-* `ignore-X` where `X` is a target detail or stage will ignore the test
-  accordingly (see below)
+* `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-test` always ignores the test. This can be used to temporarily disable
@@ -139,8 +138,8 @@ Some examples of `X` in `ignore-X` or `only-X`:
   matches that target as well as the emscripten targets.
 - Pointer width: `32bit`, `64bit`
 - Endianness: `endian-big`
+- Stage: `stage1`, `stage2`
 - Binary format: `elf`
-- Stage: `stage0`, `stage1`, `stage2`
 - Channel: `stable`, `beta`
 - When cross compiling: `cross-compile`
 - When [remote testing] is used: `remote`
@@ -196,7 +195,6 @@ settings:
 
 The following directives will check LLVM support:
 
-- `no-system-llvm` — ignores if the system llvm is used
 - `exact-llvm-major-version: 19` — ignores if the llvm major version does not
   match the specified llvm major version.
 - `min-llvm-version: 13.0` — ignored if the LLVM version is less than the given
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 9ddf0afee0c..03d4123cb02 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -24,8 +24,8 @@ collection.
 
 The test results are cached and previously successful tests are `ignored` during
 testing. The stdout/stderr contents as well as a timestamp file for every test
-can be found under `build/<target-triple>/test/` for the given
-`<target-triple>`. To force-rerun a test (e.g. in case the test runner fails to
+can be found under `build/<target-tuple>/test/` for the given
+`<target-tuple>`. To force-rerun a test (e.g. in case the test runner fails to
 notice a change) you can use the `--force-rerun` CLI option.
 
 > **Note on requirements of external dependencies**
@@ -49,7 +49,7 @@ test suite ([`tests/ui`]):
 ./x test tests/ui
 ```
 
-This will run the `ui` test suite. Of course, the choice of test suites is
+Of course, the choice of test suites is
 somewhat arbitrary, and may not suit the task you are doing. For example, if you
 are hacking on debuginfo, you may be better off with the debuginfo test suite:
 
@@ -112,8 +112,8 @@ crates, you have to specify those explicitly.
 ./x test --stage 1 library/std
 ```
 
-By listing which test suites you want to run you avoid having to run tests for
-components you did not change at all.
+By listing which test suites you want to run,
+you avoid having to run tests for components you did not change at all.
 
 <div class="warning">
 Note that bors only runs the tests with the full stage 2 build; therefore, while
@@ -172,16 +172,18 @@ additional arguments to the compiler when building the tests.
 ## Editing and updating the reference files
 
 If you have changed the compiler's output intentionally, or you are making a new
-test, you can pass `--bless` to the test subcommand. E.g. if some tests in
-`tests/ui` are failing, you can run
+test, you can pass `--bless` to the test subcommand.
+
+As an example,
+if some tests in `tests/ui` are failing, you can run this command:
 
 ```text
 ./x test tests/ui --bless
 ```
 
-to automatically adjust the `.stderr`, `.stdout` or `.fixed` files of
-all tests. Of course you can also target just specific tests with the
-`--test-args your_test_name` flag, just like when running the tests.
+It automatically adjusts the `.stderr`, `.stdout`, or `.fixed` files of all `test/ui` tests.
+Of course you can also target just specific tests with the `--test-args your_test_name` flag,
+just like when running the tests without the `--bless` flag.
 
 ## Configuring test running
 
@@ -190,7 +192,7 @@ There are a few options for running tests:
 * `config.toml` has the `rust.verbose-tests` option. If `false`, each test will
   print a single dot (the default). If `true`, the name of every test will be
   printed. This is equivalent to the `--quiet` option in the [Rust test
-  harness](https://doc.rust-lang.org/rustc/tests/)
+  harness](https://doc.rust-lang.org/rustc/tests/).
 * The environment variable `RUST_TEST_THREADS` can be set to the number of
   concurrent threads to use for testing.
 
diff --git a/src/etc/rust_analyzer_eglot.el b/src/etc/rust_analyzer_eglot.el
index 7b4309f8e18..6b40371d9af 100644
--- a/src/etc/rust_analyzer_eglot.el
+++ b/src/etc/rust_analyzer_eglot.el
@@ -8,7 +8,6 @@
                                                          "check"
                                                          "--json-output"])
                  :linkedProjects ["Cargo.toml"
-                                  "src/tools/x/Cargo.toml"
                                   "src/bootstrap/Cargo.toml"
                                   "src/tools/rust-analyzer/Cargo.toml"
                                   "compiler/rustc_codegen_cranelift/Cargo.toml"
diff --git a/src/etc/rust_analyzer_helix.toml b/src/etc/rust_analyzer_helix.toml
index afddd089eb1..05fc7716a72 100644
--- a/src/etc/rust_analyzer_helix.toml
+++ b/src/etc/rust_analyzer_helix.toml
@@ -15,7 +15,6 @@ linkedProjects = [
     "library/Cargo.toml",
     "src/bootstrap/Cargo.toml",
     "src/tools/rust-analyzer/Cargo.toml",
-    "src/tools/x/Cargo.toml",
 ]
 
 [language-server.rust-analyzer.config.check]
diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json
index b104356d44c..da7d326a512 100644
--- a/src/etc/rust_analyzer_settings.json
+++ b/src/etc/rust_analyzer_settings.json
@@ -10,7 +10,6 @@
     "rust-analyzer.linkedProjects": [
         "Cargo.toml",
         "library/Cargo.toml",
-        "src/tools/x/Cargo.toml",
         "src/bootstrap/Cargo.toml",
         "src/tools/rust-analyzer/Cargo.toml",
         "compiler/rustc_codegen_cranelift/Cargo.toml",
diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json
index 469ea050621..abc6ddbc213 100644
--- a/src/etc/rust_analyzer_zed.json
+++ b/src/etc/rust_analyzer_zed.json
@@ -22,7 +22,6 @@
         "linkedProjects": [
           "Cargo.toml",
           "library/Cargo.toml",
-          "src/tools/x/Cargo.toml",
           "src/bootstrap/Cargo.toml",
           "src/tools/rust-analyzer/Cargo.toml",
           "compiler/rustc_codegen_cranelift/Cargo.toml",
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
index 591aff0defe..ea985866a05 100644
--- a/src/tools/compiletest/src/runtest/incremental.rs
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -65,7 +65,7 @@ impl TestCx<'_> {
 
         // FIXME(#41968): Move this check to tidy?
         if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
-            self.fatal("compile-pass tests with expected warnings should be moved to ui/");
+            self.fatal("build-pass tests with expected warnings should be moved to ui/");
         }
     }
 
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 5d257029a46..0a2d3ac63a7 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -377,7 +377,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn get_global_alloc_bytes(
         &self,
         id: AllocId,
-        kind: MemoryKind,
         bytes: &[u8],
         align: Align,
     ) -> InterpResult<'tcx, MiriAllocBytes> {
@@ -386,7 +385,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`.
             // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case
             // this function gets called before the first time `addr_from_alloc_id` gets called.
-            this.addr_from_alloc_id(id, kind)?;
+            this.addr_from_alloc_id(id, MiriMemoryKind::Global.into())?;
             // The memory we need here will have already been allocated during an earlier call to
             // `addr_from_alloc_id` for this allocation. So don't create a new `MiriAllocBytes` here, instead
             // fetch the previously prepared bytes from `prepared_alloc_bytes`.
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index dbb092f6728..90beffbf830 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -814,6 +814,59 @@ impl<'tcx> MiriMachine<'tcx> {
             .and_then(|(_allocated, deallocated)| *deallocated)
             .map(Span::data)
     }
+
+    fn init_allocation(
+        ecx: &MiriInterpCx<'tcx>,
+        id: AllocId,
+        kind: MemoryKind,
+        size: Size,
+        align: Align,
+    ) -> InterpResult<'tcx, AllocExtra<'tcx>> {
+        if ecx.machine.tracked_alloc_ids.contains(&id) {
+            ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind));
+        }
+
+        let borrow_tracker = ecx
+            .machine
+            .borrow_tracker
+            .as_ref()
+            .map(|bt| bt.borrow_mut().new_allocation(id, size, kind, &ecx.machine));
+
+        let data_race = ecx.machine.data_race.as_ref().map(|data_race| {
+            data_race::AllocState::new_allocation(
+                data_race,
+                &ecx.machine.threads,
+                size,
+                kind,
+                ecx.machine.current_span(),
+            )
+        });
+        let weak_memory = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
+
+        // If an allocation is leaked, we want to report a backtrace to indicate where it was
+        // allocated. We don't need to record a backtrace for allocations which are allowed to
+        // leak.
+        let backtrace = if kind.may_leak() || !ecx.machine.collect_leak_backtraces {
+            None
+        } else {
+            Some(ecx.generate_stacktrace())
+        };
+
+        if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
+            ecx.machine
+                .allocation_spans
+                .borrow_mut()
+                .insert(id, (ecx.machine.current_span(), None));
+        }
+
+        interp_ok(AllocExtra {
+            borrow_tracker,
+            data_race,
+            weak_memory,
+            backtrace,
+            sync: FxHashMap::default(),
+        })
+    }
 }
 
 impl VisitProvenance for MiriMachine<'_> {
@@ -1200,57 +1253,15 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         }
     }
 
-    fn init_alloc_extra(
+    fn init_local_allocation(
         ecx: &MiriInterpCx<'tcx>,
         id: AllocId,
         kind: MemoryKind,
         size: Size,
         align: Align,
     ) -> InterpResult<'tcx, Self::AllocExtra> {
-        if ecx.machine.tracked_alloc_ids.contains(&id) {
-            ecx.emit_diagnostic(NonHaltingDiagnostic::CreatedAlloc(id, size, align, kind));
-        }
-
-        let borrow_tracker = ecx
-            .machine
-            .borrow_tracker
-            .as_ref()
-            .map(|bt| bt.borrow_mut().new_allocation(id, size, kind, &ecx.machine));
-
-        let data_race = ecx.machine.data_race.as_ref().map(|data_race| {
-            data_race::AllocState::new_allocation(
-                data_race,
-                &ecx.machine.threads,
-                size,
-                kind,
-                ecx.machine.current_span(),
-            )
-        });
-        let weak_memory = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation);
-
-        // If an allocation is leaked, we want to report a backtrace to indicate where it was
-        // allocated. We don't need to record a backtrace for allocations which are allowed to
-        // leak.
-        let backtrace = if kind.may_leak() || !ecx.machine.collect_leak_backtraces {
-            None
-        } else {
-            Some(ecx.generate_stacktrace())
-        };
-
-        if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
-            ecx.machine
-                .allocation_spans
-                .borrow_mut()
-                .insert(id, (ecx.machine.current_span(), None));
-        }
-
-        interp_ok(AllocExtra {
-            borrow_tracker,
-            data_race,
-            weak_memory,
-            backtrace,
-            sync: FxHashMap::default(),
-        })
+        assert!(kind != MiriMemoryKind::Global.into());
+        MiriMachine::init_allocation(ecx, id, kind, size, align)
     }
 
     fn adjust_alloc_root_pointer(
@@ -1340,13 +1351,13 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         alloc: &'b Allocation,
     ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
     {
-        let kind = Self::GLOBAL_KIND.unwrap().into();
         let alloc = alloc.adjust_from_tcx(
             &ecx.tcx,
-            |bytes, align| ecx.get_global_alloc_bytes(id, kind, bytes, align),
+            |bytes, align| ecx.get_global_alloc_bytes(id, bytes, align),
             |ptr| ecx.global_root_pointer(ptr),
         )?;
-        let extra = Self::init_alloc_extra(ecx, id, kind, alloc.size(), alloc.align)?;
+        let kind = MiriMemoryKind::Global.into();
+        let extra = MiriMachine::init_allocation(ecx, id, kind, alloc.size(), alloc.align)?;
         interp_ok(Cow::Owned(alloc.with_extra(extra)))
     }
 
diff --git a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr
index 5162368b51f..e8babf02163 100644
--- a/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/aliasing_mut4.tree.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: write access through <TAG> at ALLOC[0x0] is forbidden
   --> RUSTLIB/core/src/mem/mod.rs:LL:CC
    |
-LL |         ptr::write(dest, src);
-   |         ^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
+LL |         crate::intrinsics::write_via_move(dest, src);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ write access through <TAG> at ALLOC[0x0] is forbidden
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
    = help: the accessed tag <TAG> is foreign to the protected tag <TAG> (i.e., it is not a child)
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 8b3bd77141b..c8759bb6ff6 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -1,3 +1,5 @@
+use std::path::Path;
+
 use anyhow::Context;
 use camino::{Utf8Path, Utf8PathBuf};
 
@@ -86,36 +88,57 @@ llvm-config = "{llvm_config}"
     log::info!("Using following `config.toml` for running tests:\n{config_content}");
 
     // Simulate a stage 0 compiler with the extracted optimized dist artifacts.
-    std::fs::write("config.toml", config_content)?;
-
-    let x_py = env.checkout_path().join("x.py");
-    let mut args = vec![
-        env.python_binary(),
-        x_py.as_str(),
-        "test",
-        "--build",
-        env.host_tuple(),
-        "--stage",
-        "0",
-        "tests/assembly",
-        "tests/codegen",
-        "tests/codegen-units",
-        "tests/incremental",
-        "tests/mir-opt",
-        "tests/pretty",
-        "tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
-        "tests/ui",
-        "tests/crashes",
-    ];
-    for test_path in env.skipped_tests() {
-        args.extend(["--skip", test_path]);
+    with_backed_up_file(Path::new("config.toml"), &config_content, || {
+        let x_py = env.checkout_path().join("x.py");
+        let mut args = vec![
+            env.python_binary(),
+            x_py.as_str(),
+            "test",
+            "--build",
+            env.host_tuple(),
+            "--stage",
+            "0",
+            "tests/assembly",
+            "tests/codegen",
+            "tests/codegen-units",
+            "tests/incremental",
+            "tests/mir-opt",
+            "tests/pretty",
+            "tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
+            "tests/ui",
+            "tests/crashes",
+        ];
+        for test_path in env.skipped_tests() {
+            args.extend(["--skip", test_path]);
+        }
+        cmd(&args)
+            .env("COMPILETEST_FORCE_STAGE0", "1")
+            // Also run dist-only tests
+            .env("COMPILETEST_ENABLE_DIST_TESTS", "1")
+            .run()
+            .context("Cannot execute tests")
+    })
+}
+
+/// Backup `path` (if it exists), then write `contents` into it, and then restore the original
+/// contents of the file.
+fn with_backed_up_file<F>(path: &Path, contents: &str, func: F) -> anyhow::Result<()>
+where
+    F: FnOnce() -> anyhow::Result<()>,
+{
+    let original_contents =
+        if path.is_file() { Some(std::fs::read_to_string(path)?) } else { None };
+
+    // Overwrite it with new contents
+    std::fs::write(path, contents)?;
+
+    let ret = func();
+
+    if let Some(original_contents) = original_contents {
+        std::fs::write(path, original_contents)?;
     }
-    cmd(&args)
-        .env("COMPILETEST_FORCE_STAGE0", "1")
-        // Also run dist-only tests
-        .env("COMPILETEST_ENABLE_DIST_TESTS", "1")
-        .run()
-        .context("Cannot execute tests")
+
+    ret
 }
 
 /// Tries to find the version of the dist artifacts (either nightly, beta, or 1.XY.Z).
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index ddcf315a267..e54747c129a 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -553,6 +553,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
 name = "html5ever"
 version = "0.27.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -874,9 +880,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.45"
+version = "0.4.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b07d36d96ffe1b5b16ddf2bc80b3b26bb7a498b2a6591061250bf0af8e8095ad"
+checksum = "7e1a8fe3a4a01f28dab245c474cb7b95ccb4d3d2f17a5419a3d949f474c45e84"
 dependencies = [
  "ammonia",
  "anyhow",
@@ -886,6 +892,7 @@ dependencies = [
  "elasticlunr-rs",
  "env_logger",
  "handlebars",
+ "hex",
  "log",
  "memchr",
  "once_cell",
@@ -894,6 +901,7 @@ dependencies = [
  "regex",
  "serde",
  "serde_json",
+ "sha2",
  "shlex",
  "tempfile",
  "toml 0.5.11",
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 6aec0bec0fa..831233e3065 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -15,6 +15,6 @@ mdbook-i18n-helpers = "0.3.3"
 mdbook-spec = { path = "../../doc/reference/mdbook-spec" }
 
 [dependencies.mdbook]
-version = "0.4.45"
+version = "0.4.47"
 default-features = false
 features = ["search"]
diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index 33f2a51215d..4b510e308c9 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -151,6 +151,7 @@ fn get_book_dir(args: &ArgMatches) -> PathBuf {
 fn load_book(book_dir: &Path) -> Result3<MDBook> {
     let mut book = MDBook::load(book_dir)?;
     book.config.set("output.html.input-404", "").unwrap();
+    book.config.set("output.html.hash-files", true).unwrap();
     Ok(book)
 }
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 569d3c67b04..81c55ecaa7a 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -81,7 +81,6 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>,
     ("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None, &[]),
     ("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]),
     ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]),
-    ("src/tools/x", &[], None, &[]),
     // tidy-alphabetical-end
 ];
 
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index bc3519142dd..4078d462f55 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -29,6 +29,7 @@ fn main() {
         FromStr::from_str(&env::args().nth(4).expect("need concurrency"))
             .expect("concurrency must be a number");
 
+    let root_manifest = root_path.join("Cargo.toml");
     let src_path = root_path.join("src");
     let tests_path = root_path.join("tests");
     let library_path = root_path.join("library");
@@ -137,6 +138,7 @@ fn main() {
         check!(edition, &compiler_path);
         check!(edition, &library_path);
 
+        check!(alphabetical, &root_manifest);
         check!(alphabetical, &src_path);
         check!(alphabetical, &tests_path);
         check!(alphabetical, &compiler_path);
diff --git a/src/tools/x/Cargo.lock b/src/tools/x/Cargo.lock
deleted file mode 100644
index 09e5c750749..00000000000
--- a/src/tools/x/Cargo.lock
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "x"
-version = "0.1.1"
diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs
index e5978bfc761..c1f208d7909 100644
--- a/tests/codegen/enum/enum-two-variants-match.rs
+++ b/tests/codegen/enum/enum-two-variants-match.rs
@@ -7,19 +7,22 @@
 // CHECK-LABEL: @option_match
 #[no_mangle]
 pub fn option_match(x: Option<i32>) -> u16 {
-    // CHECK: %x = alloca [8 x i8]
-    // CHECK: store i32 %0, ptr %x
-    // CHECK: %[[TAG:.+]] = load i32, ptr %x
-    // CHECK-SAME: !range ![[ZERO_ONE_32:[0-9]+]]
-    // CHECK: %[[DISCR:.+]] = zext i32 %[[TAG]] to i64
+    // CHECK-NOT: %x = alloca
+    // CHECK: %[[OUT:.+]] = alloca [2 x i8]
+    // CHECK-NOT: %x = alloca
+
+    // CHECK: %[[DISCR:.+]] = zext i32 %x.0 to i64
     // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1
     // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]]
 
     // CHECK: [[TRUE]]:
-    // CHECK: store i16 13
+    // CHECK: store i16 13, ptr %[[OUT]]
 
     // CHECK: [[FALSE]]:
-    // CHECK: store i16 42
+    // CHECK: store i16 42, ptr %[[OUT]]
+
+    // CHECK: %[[RET:.+]] = load i16, ptr %[[OUT]]
+    // CHECK: ret i16 %[[RET]]
     match x {
         Some(_) => 13,
         None => 42,
@@ -29,23 +32,23 @@ pub fn option_match(x: Option<i32>) -> u16 {
 // CHECK-LABEL: @result_match
 #[no_mangle]
 pub fn result_match(x: Result<u64, i64>) -> u16 {
-    // CHECK: %x = alloca [16 x i8]
-    // CHECK: store i64 %0, ptr %x
-    // CHECK: %[[DISCR:.+]] = load i64, ptr %x
-    // CHECK-SAME: !range ![[ZERO_ONE_64:[0-9]+]]
-    // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1
+    // CHECK-NOT: %x = alloca
+    // CHECK: %[[OUT:.+]] = alloca [2 x i8]
+    // CHECK-NOT: %x = alloca
+
+    // CHECK: %[[COND:.+]] = trunc nuw i64 %x.0 to i1
     // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]]
 
     // CHECK: [[TRUE]]:
-    // CHECK: store i16 13
+    // CHECK: store i16 13, ptr %[[OUT]]
 
     // CHECK: [[FALSE]]:
-    // CHECK: store i16 42
+    // CHECK: store i16 42, ptr %[[OUT]]
+
+    // CHECK: %[[RET:.+]] = load i16, ptr %[[OUT]]
+    // CHECK: ret i16 %[[RET]]
     match x {
         Err(_) => 13,
         Ok(_) => 42,
     }
 }
-
-// CHECK: ![[ZERO_ONE_32]] = !{i32 0, i32 2}
-// CHECK: ![[ZERO_ONE_64]] = !{i64 0, i64 2}
diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs
index 54ee473e620..0891c878fd9 100644
--- a/tests/codegen/intrinsics/cold_path2.rs
+++ b/tests/codegen/intrinsics/cold_path2.rs
@@ -25,8 +25,8 @@ pub fn test(x: Option<bool>) {
         path_b();
     }
 
-    // CHECK-LABEL: @test(
-    // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %0, 2
+    // CHECK-LABEL: void @test(i8{{.+}}%x)
+    // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %x, 2
     // CHECK: br i1 %[[IS_NONE]], label %bb2, label %bb1, !prof ![[NUM:[0-9]+]]
     // CHECK: bb1:
     // CHECK: path_a
diff --git a/tests/codegen/match-optimizes-away.rs b/tests/codegen/match-optimizes-away.rs
index 8a70d993423..5e9be72a09f 100644
--- a/tests/codegen/match-optimizes-away.rs
+++ b/tests/codegen/match-optimizes-away.rs
@@ -1,5 +1,4 @@
-//
-//@ compile-flags: -Copt-level=3
+//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
 #![crate_type = "lib"]
 
 pub enum Three {
@@ -18,9 +17,9 @@ pub enum Four {
 
 #[no_mangle]
 pub fn three_valued(x: Three) -> Three {
-    // CHECK-LABEL: @three_valued
+    // CHECK-LABEL: i8 @three_valued(i8{{.+}}%x)
     // CHECK-NEXT: {{^.*:$}}
-    // CHECK-NEXT: ret i8 %0
+    // CHECK-NEXT: ret i8 %x
     match x {
         Three::A => Three::A,
         Three::B => Three::B,
@@ -30,9 +29,9 @@ pub fn three_valued(x: Three) -> Three {
 
 #[no_mangle]
 pub fn four_valued(x: Four) -> Four {
-    // CHECK-LABEL: @four_valued
+    // CHECK-LABEL: i16 @four_valued(i16{{.+}}%x)
     // CHECK-NEXT: {{^.*:$}}
-    // CHECK-NEXT: ret i16 %0
+    // CHECK-NEXT: ret i16 %x
     match x {
         Four::A => Four::A,
         Four::B => Four::B,
diff --git a/tests/codegen/range-loop.rs b/tests/codegen/range-loop.rs
new file mode 100644
index 00000000000..b131beb40dd
--- /dev/null
+++ b/tests/codegen/range-loop.rs
@@ -0,0 +1,44 @@
+//@ ignore-std-debug-assertions
+//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+// Ensure that MIR optimizations have cleaned things up enough that the IR we
+// emit is good even without running the LLVM optimizations.
+
+// CHECK-NOT: define
+
+// CHECK-LABEL: define{{.+}}void @call_for_zero_to_n
+#[no_mangle]
+pub fn call_for_zero_to_n(n: u32, f: fn(u32)) {
+    // CHECK: start:
+    // CHECK-NOT: alloca
+    // CHECK: %[[IND:.+]] = alloca [4 x i8]
+    // CHECK-NEXT: %[[ALWAYS_SOME_OPTION:.+]] = alloca
+    // CHECK-NOT: alloca
+    // CHECK: store i32 0, ptr %[[IND]],
+    // CHECK: br label %[[HEAD:.+]]
+
+    // CHECK: [[HEAD]]:
+    // CHECK: %[[T1:.+]] = load i32, ptr %[[IND]],
+    // CHECK: %[[NOT_DONE:.+]] = icmp ult i32 %[[T1]], %n
+    // CHECK: br i1 %[[NOT_DONE]], label %[[BODY:.+]], label %[[BREAK:.+]]
+
+    // CHECK: [[BREAK]]:
+    // CHECK: ret void
+
+    // CHECK: [[BODY]]:
+    // CHECK: %[[T2:.+]] = load i32, ptr %[[IND]],
+    // CHECK: %[[T3:.+]] = add nuw i32 %[[T2]], 1
+    // CHECK: store i32 %[[T3]], ptr %[[IND]],
+
+    // CHECK: store i32 %[[T2]]
+    // CHECK: %[[T4:.+]] = load i32
+    // CHECK: call void %f(i32{{.+}}%[[T4]])
+
+    for i in 0..n {
+        f(i);
+    }
+}
+
+// CHECK-NOT: define
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index ca15e510173..23a084c51f4 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -17,10 +17,10 @@ use std::ptr::NonNull;
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
     // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
-    // TWENTY-NEXT: %.2 = select i1 %[[IS_SOME]], i32 %1, i32 undef
+    // TWENTY-NEXT: %[[PAYLOAD:.+]] = select i1 %[[IS_SOME]], i32 %1, i32 undef
     // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
     // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
-    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %.2, 1
+    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %[[PAYLOAD]], 1
     // CHECK-NEXT: ret { i32, i32 } [[REG2]]
     match x {
         Some(x) => Some(x),
@@ -33,7 +33,7 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
 pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
     // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
-    // TWENTY-NEXT: %.1 = select i1 %[[IS_SOME]], i32 %1, i32 undef
+    // TWENTY-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: ret { i32, i32 }
diff --git a/tests/crashes/125059.rs b/tests/crashes/125059.rs
deleted file mode 100644
index 7e9f7414816..00000000000
--- a/tests/crashes/125059.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: rust-lang/rust#125059
-#![feature(deref_patterns)]
-#![allow(incomplete_features)]
-
-fn simple_vec(vec: Vec<u32>) -> u32 {
-   (|| match Vec::<u32>::new() {
-        deref!([]) => 100,
-        _ => 2000,
-    })()
-}
-
-fn main() {}
diff --git a/tests/mir-opt/inline/exponential_runtime.rs b/tests/mir-opt/inline/exponential_runtime.rs
index 1199ce4e558..62c1d8be1bf 100644
--- a/tests/mir-opt/inline/exponential_runtime.rs
+++ b/tests/mir-opt/inline/exponential_runtime.rs
@@ -87,10 +87,15 @@ fn main() {
     // CHECK-LABEL: fn main(
     // CHECK-NOT: inlined
     // CHECK: (inlined <() as G>::call)
+    // CHECK-NOT: inlined
     // CHECK: (inlined <() as F>::call)
+    // CHECK-NOT: inlined
     // CHECK: (inlined <() as E>::call)
+    // CHECK-NOT: inlined
     // CHECK: (inlined <() as D>::call)
+    // CHECK-NOT: inlined
     // CHECK: (inlined <() as C>::call)
+    // CHECK-NOT: inlined
     // CHECK: (inlined <() as B>::call)
     // CHECK-NOT: inlined
     <() as G>::call();
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
index 75fc2ea16e3..f099d763c3d 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
@@ -6,6 +6,7 @@
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
 +     let mut _7: ();
++     let mut _8: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -17,6 +18,10 @@
 +             scope 3 {
 +                 debug b => _6;
 +             }
++             scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++                 scope 7 (inlined sleep) {
++                 }
++             }
 +         }
 +         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
 +             scope 5 (inlined sleep) {
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index 407cb24df67..c33e0810739 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -6,6 +6,7 @@
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
 +     let mut _8: ();
++     let mut _9: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -18,6 +19,10 @@
 +             scope 3 {
 +                 debug b => _6;
 +             }
++             scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++                 scope 7 (inlined sleep) {
++                 }
++             }
 +         }
 +         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
 +             scope 5 (inlined sleep) {
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
index 1e33e222b27..eb97af1e284 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
@@ -55,10 +55,46 @@
 +                         let _26: ();
 +                         scope 9 {
 +                         }
++                         scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
++                         }
++                         scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
++                             let mut _42: ();
++                             let mut _43: std::option::Option<()>;
++                             let mut _44: &mut std::option::Option<()>;
++                             let mut _45: &mut std::future::Ready<()>;
++                             let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>;
++                             scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
++                                 let mut _47: std::pin::Pin<&mut std::future::Ready<()>>;
++                                 scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
++                                     let mut _48: &mut &mut std::future::Ready<()>;
++                                     scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
++                                     }
++                                     scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
++                                     }
++                                 }
++                                 scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) {
++                                 }
++                             }
++                             scope 19 (inlined Option::<()>::take) {
++                                 let mut _49: std::option::Option<()>;
++                                 scope 20 (inlined std::mem::replace::<Option<()>>) {
++                                     scope 21 {
++                                     }
++                                 }
++                             }
++                             scope 22 (inlined #[track_caller] Option::<()>::expect) {
++                                 let mut _50: isize;
++                                 let mut _51: !;
++                                 scope 23 {
++                                 }
++                             }
++                         }
 +                     }
 +                     scope 10 (inlined ready::<()>) {
 +                         let mut _41: std::option::Option<()>;
 +                     }
++                     scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
++                     }
 +                 }
 +             }
           }
@@ -113,7 +149,7 @@
 +         StorageLive(_40);
 +         _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         _32 = discriminant((*_33));
-+         switchInt(move _32) -> [0: bb3, 1: bb13, 3: bb12, otherwise: bb8];
++         switchInt(move _32) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5];
       }
   
 -     bb3: {
@@ -164,19 +200,16 @@
 +         _13 = std::future::Ready::<()>(move _41);
 +         StorageDead(_41);
 +         StorageDead(_14);
-+         _12 = <std::future::Ready<()> as IntoFuture>::into_future(move _13) -> [return: bb4, unwind unreachable];
-+     }
-+ 
-      bb4: {
--         StorageDead(_2);
--         return;
++         _12 = move _13;
 +         StorageDead(_13);
 +         _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
-+         goto -> bb5;
++         goto -> bb4;
 +     }
 + 
-+     bb5: {
+      bb4: {
+-         StorageDead(_2);
+-         return;
 +         StorageLive(_17);
 +         StorageLive(_18);
 +         StorageLive(_19);
@@ -185,10 +218,7 @@
 +         _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
 +         _20 = &mut (*_21);
-+         _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb6, unwind unreachable];
-+     }
-+ 
-+     bb6: {
++         _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 };
 +         StorageDead(_20);
 +         StorageLive(_22);
 +         StorageLive(_23);
@@ -197,21 +227,36 @@
 +         _23 = move _24;
 +         _22 = &mut (*_23);
 +         StorageDead(_24);
-+         _18 = <std::future::Ready<()> as Future>::poll(move _19, move _22) -> [return: bb7, unwind unreachable];
-+     }
-+ 
-+     bb7: {
-+         StorageDead(_22);
-+         StorageDead(_19);
-+         _25 = discriminant(_18);
-+         switchInt(move _25) -> [0: bb10, 1: bb9, otherwise: bb8];
++         StorageLive(_45);
++         StorageLive(_46);
++         StorageLive(_49);
++         StorageLive(_51);
++         StorageLive(_42);
++         StorageLive(_43);
++         StorageLive(_44);
++         _46 = &mut _19;
++         StorageLive(_47);
++         StorageLive(_48);
++         _48 = &mut (_19.0: &mut std::future::Ready<()>);
++         _45 = copy (_19.0: &mut std::future::Ready<()>);
++         StorageDead(_48);
++         _47 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _45 };
++         StorageDead(_47);
++         _44 = &mut ((*_45).0: std::option::Option<()>);
++         _49 = Option::<()>::None;
++         _43 = copy ((*_45).0: std::option::Option<()>);
++         ((*_45).0: std::option::Option<()>) = copy _49;
++         StorageDead(_44);
++         StorageLive(_50);
++         _50 = discriminant(_43);
++         switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5];
 +     }
 + 
-+     bb8: {
++     bb5: {
 +         unreachable;
 +     }
 + 
-+     bb9: {
++     bb6: {
 +         _17 = const ();
 +         StorageDead(_23);
 +         StorageDead(_21);
@@ -229,7 +274,7 @@
 +         goto -> bb2;
 +     }
 + 
-+     bb10: {
++     bb7: {
 +         StorageLive(_26);
 +         _26 = copy ((_18 as Ready).0: ());
 +         _30 = copy _26;
@@ -240,17 +285,17 @@
 +         StorageDead(_17);
 +         StorageDead(_12);
 +         _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
-+         drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb11, unwind unreachable];
++         drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable];
 +     }
 + 
-+     bb11: {
++     bb8: {
 +         _7 = Poll::<()>::Ready(move _30);
 +         _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         discriminant((*_40)) = 1;
 +         goto -> bb2;
 +     }
 + 
-+     bb12: {
++     bb9: {
 +         StorageLive(_12);
 +         StorageLive(_28);
 +         StorageLive(_29);
@@ -259,11 +304,31 @@
 +         _31 = move _28;
 +         StorageDead(_28);
 +         _16 = const ();
-+         goto -> bb5;
++         goto -> bb4;
 +     }
 + 
-+     bb13: {
-+         assert(const false, "`async fn` resumed after completion") -> [success: bb13, unwind unreachable];
++     bb10: {
++         assert(const false, "`async fn` resumed after completion") -> [success: bb10, unwind unreachable];
++     }
++ 
++     bb11: {
++         _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
++     }
++ 
++     bb12: {
++         _42 = move ((_43 as Some).0: ());
++         StorageDead(_50);
++         StorageDead(_43);
++         _18 = Poll::<()>::Ready(move _42);
++         StorageDead(_42);
++         StorageDead(_51);
++         StorageDead(_49);
++         StorageDead(_46);
++         StorageDead(_45);
++         StorageDead(_22);
++         StorageDead(_19);
++         _25 = discriminant(_18);
++         switchInt(move _25) -> [0: bb7, 1: bb6, otherwise: bb5];
       }
   }
   
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
index b1840beb3ef..eb757e09114 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
@@ -57,10 +57,46 @@
 +                         let _26: ();
 +                         scope 9 {
 +                         }
++                         scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
++                         }
++                         scope 13 (inlined <std::future::Ready<()> as Future>::poll) {
++                             let mut _44: ();
++                             let mut _45: std::option::Option<()>;
++                             let mut _46: &mut std::option::Option<()>;
++                             let mut _47: &mut std::future::Ready<()>;
++                             let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>;
++                             scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
++                                 let mut _49: std::pin::Pin<&mut std::future::Ready<()>>;
++                                 scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
++                                     let mut _50: &mut &mut std::future::Ready<()>;
++                                     scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
++                                     }
++                                     scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
++                                     }
++                                 }
++                                 scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) {
++                                 }
++                             }
++                             scope 19 (inlined Option::<()>::take) {
++                                 let mut _51: std::option::Option<()>;
++                                 scope 20 (inlined std::mem::replace::<Option<()>>) {
++                                     scope 21 {
++                                     }
++                                 }
++                             }
++                             scope 22 (inlined #[track_caller] Option::<()>::expect) {
++                                 let mut _52: isize;
++                                 let mut _53: !;
++                                 scope 23 {
++                                 }
++                             }
++                         }
 +                     }
 +                     scope 10 (inlined ready::<()>) {
 +                         let mut _43: std::option::Option<()>;
 +                     }
++                     scope 11 (inlined <std::future::Ready<()> as IntoFuture>::into_future) {
++                     }
 +                 }
 +             }
           }
@@ -117,7 +153,7 @@
 +         StorageLive(_42);
 +         _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         _32 = discriminant((*_33));
-+         switchInt(move _32) -> [0: bb5, 1: bb22, 2: bb21, 3: bb20, otherwise: bb10];
++         switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7];
       }
   
 -     bb3: {
@@ -181,21 +217,16 @@
 +         _13 = std::future::Ready::<()>(move _43);
 +         StorageDead(_43);
 +         StorageDead(_14);
-+         _12 = <std::future::Ready<()> as IntoFuture>::into_future(move _13) -> [return: bb6, unwind: bb17];
-      }
-  
--     bb5 (cleanup): {
--         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
-+     bb6: {
++         _12 = move _13;
 +         StorageDead(_13);
 +         _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         (((*_36) as variant#3).1: std::future::Ready<()>) = move _12;
-+         goto -> bb7;
++         goto -> bb6;
       }
   
--     bb6 (cleanup): {
--         resume;
-+     bb7: {
+-     bb5 (cleanup): {
+-         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
++     bb6: {
 +         StorageLive(_17);
 +         StorageLive(_18);
 +         StorageLive(_19);
@@ -204,10 +235,7 @@
 +         _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>);
 +         _20 = &mut (*_21);
-+         _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb8, unwind: bb15];
-+     }
-+ 
-+     bb8: {
++         _19 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _20 };
 +         StorageDead(_20);
 +         StorageLive(_22);
 +         StorageLive(_23);
@@ -216,21 +244,38 @@
 +         _23 = move _24;
 +         _22 = &mut (*_23);
 +         StorageDead(_24);
-+         _18 = <std::future::Ready<()> as Future>::poll(move _19, move _22) -> [return: bb9, unwind: bb14];
-+     }
-+ 
-+     bb9: {
-+         StorageDead(_22);
-+         StorageDead(_19);
-+         _25 = discriminant(_18);
-+         switchInt(move _25) -> [0: bb12, 1: bb11, otherwise: bb10];
-+     }
-+ 
-+     bb10: {
++         StorageLive(_47);
++         StorageLive(_48);
++         StorageLive(_51);
++         StorageLive(_53);
++         StorageLive(_44);
++         StorageLive(_45);
++         StorageLive(_46);
++         _48 = &mut _19;
++         StorageLive(_49);
++         StorageLive(_50);
++         _50 = &mut (_19.0: &mut std::future::Ready<()>);
++         _47 = copy (_19.0: &mut std::future::Ready<()>);
++         StorageDead(_50);
++         _49 = Pin::<&mut std::future::Ready<()>> { __pointer: copy _47 };
++         StorageDead(_49);
++         _46 = &mut ((*_47).0: std::option::Option<()>);
++         _51 = Option::<()>::None;
++         _45 = copy ((*_47).0: std::option::Option<()>);
++         ((*_47).0: std::option::Option<()>) = copy _51;
++         StorageDead(_46);
++         StorageLive(_52);
++         _52 = discriminant(_45);
++         switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7];
+      }
+  
+-     bb6 (cleanup): {
+-         resume;
++     bb7: {
 +         unreachable;
 +     }
 + 
-+     bb11: {
++     bb8: {
 +         _17 = const ();
 +         StorageDead(_23);
 +         StorageDead(_21);
@@ -248,7 +293,7 @@
 +         goto -> bb4;
 +     }
 + 
-+     bb12: {
++     bb9: {
 +         StorageLive(_26);
 +         _26 = copy ((_18 as Ready).0: ());
 +         _30 = copy _26;
@@ -259,54 +304,35 @@
 +         StorageDead(_17);
 +         StorageDead(_12);
 +         _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
-+         drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb13, unwind: bb19];
++         drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12];
 +     }
 + 
-+     bb13: {
++     bb10: {
 +         _7 = Poll::<()>::Ready(move _30);
 +         _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         discriminant((*_40)) = 1;
 +         goto -> bb4;
 +     }
 + 
-+     bb14 (cleanup): {
++     bb11 (cleanup): {
 +         StorageDead(_22);
 +         StorageDead(_19);
 +         StorageDead(_23);
-+         goto -> bb16;
-+     }
-+ 
-+     bb15 (cleanup): {
-+         StorageDead(_20);
-+         StorageDead(_19);
-+         goto -> bb16;
-+     }
-+ 
-+     bb16 (cleanup): {
 +         StorageDead(_21);
 +         StorageDead(_18);
 +         StorageDead(_17);
-+         goto -> bb18;
-+     }
-+ 
-+     bb17 (cleanup): {
-+         StorageDead(_13);
-+         goto -> bb18;
-+     }
-+ 
-+     bb18 (cleanup): {
 +         StorageDead(_12);
 +         _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
-+         drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb19, unwind terminate(cleanup)];
++         drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)];
 +     }
 + 
-+     bb19 (cleanup): {
++     bb12 (cleanup): {
 +         _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()});
 +         discriminant((*_42)) = 2;
 +         goto -> bb2;
 +     }
 + 
-+     bb20: {
++     bb13: {
 +         StorageLive(_12);
 +         StorageLive(_28);
 +         StorageLive(_29);
@@ -315,15 +341,35 @@
 +         _31 = move _28;
 +         StorageDead(_28);
 +         _16 = const ();
-+         goto -> bb7;
++         goto -> bb6;
 +     }
 + 
-+     bb21: {
-+         assert(const false, "`async fn` resumed after panicking") -> [success: bb21, unwind: bb2];
++     bb14: {
++         assert(const false, "`async fn` resumed after panicking") -> [success: bb14, unwind: bb2];
 +     }
 + 
-+     bb22: {
-+         assert(const false, "`async fn` resumed after completion") -> [success: bb22, unwind: bb2];
++     bb15: {
++         assert(const false, "`async fn` resumed after completion") -> [success: bb15, unwind: bb2];
++     }
++ 
++     bb16: {
++         _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
++     }
++ 
++     bb17: {
++         _44 = move ((_45 as Some).0: ());
++         StorageDead(_52);
++         StorageDead(_45);
++         _18 = Poll::<()>::Ready(move _44);
++         StorageDead(_44);
++         StorageDead(_53);
++         StorageDead(_51);
++         StorageDead(_48);
++         StorageDead(_47);
++         StorageDead(_22);
++         StorageDead(_19);
++         _25 = discriminant(_18);
++         switchInt(move _25) -> [0: bb9, 1: bb8, otherwise: bb7];
       }
   }
   
diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
index be69bbf10e7..1f9c464d633 100644
--- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
@@ -26,6 +26,18 @@ fn int_range(_1: usize, _2: usize) -> () {
                 let mut _12: usize;
                 scope 6 {
                     debug old => _11;
+                    scope 8 (inlined <usize as Step>::forward_unchecked) {
+                        debug start => _11;
+                        debug n => const 1_usize;
+                        scope 9 (inlined core::num::<impl usize>::unchecked_add) {
+                            debug self => _11;
+                            debug rhs => const 1_usize;
+                            scope 10 (inlined core::ub_checks::check_language_ub) {
+                                scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
+                                }
+                            }
+                        }
+                    }
                 }
                 scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _6;
@@ -50,7 +62,6 @@ fn int_range(_1: usize, _2: usize) -> () {
     bb1: {
         StorageLive(_13);
         _5 = &mut _4;
-        StorageLive(_11);
         StorageLive(_10);
         StorageLive(_6);
         _6 = &(_4.0: usize);
@@ -70,7 +81,6 @@ fn int_range(_1: usize, _2: usize) -> () {
         StorageDead(_7);
         StorageDead(_6);
         StorageDead(_10);
-        StorageDead(_11);
         StorageDead(_13);
         StorageDead(_4);
         return;
@@ -81,20 +91,16 @@ fn int_range(_1: usize, _2: usize) -> () {
         StorageDead(_6);
         _11 = copy (_4.0: usize);
         StorageLive(_12);
-        _12 = <usize as Step>::forward_unchecked(copy _11, const 1_usize) -> [return: bb4, unwind continue];
-    }
-
-    bb4: {
+        _12 = AddUnchecked(copy _11, const 1_usize);
         (_4.0: usize) = move _12;
         StorageDead(_12);
         _13 = Option::<usize>::Some(copy _11);
         StorageDead(_10);
-        StorageDead(_11);
         _14 = copy ((_13 as Some).0: usize);
-        _15 = opaque::<usize>(move _14) -> [return: bb5, unwind continue];
+        _15 = opaque::<usize>(move _14) -> [return: bb4, unwind continue];
     }
 
-    bb5: {
+    bb4: {
         StorageDead(_13);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
index ed494f6e74c..958a06bcd34 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
@@ -6,10 +6,6 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
     let mut _0: u32;
     scope 1 (inlined std::mem::replace::<u32>) {
         scope 2 {
-            scope 4 (inlined std::ptr::write::<u32>) {
-            }
-        }
-        scope 3 (inlined std::ptr::read::<u32>) {
         }
     }
 
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
index ed494f6e74c..958a06bcd34 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
@@ -6,10 +6,6 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
     let mut _0: u32;
     scope 1 (inlined std::mem::replace::<u32>) {
         scope 2 {
-            scope 4 (inlined std::ptr::write::<u32>) {
-            }
-        }
-        scope 3 (inlined std::ptr::read::<u32>) {
         }
     }
 
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 5d33c33d73f..0aa37203c1b 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -23,6 +23,14 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let _7: u32;
                 let mut _8: u32;
                 scope 6 {
+                    scope 8 (inlined <u32 as Step>::forward_unchecked) {
+                        scope 9 (inlined core::num::<impl u32>::unchecked_add) {
+                            scope 10 (inlined core::ub_checks::check_language_ub) {
+                                scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
+                                }
+                            }
+                        }
+                    }
                 }
                 scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     let mut _5: u32;
@@ -41,7 +49,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
 
     bb1: {
         StorageLive(_9);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = copy _4;
@@ -52,7 +59,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
 
     bb2: {
         StorageDead(_6);
-        StorageDead(_7);
         StorageDead(_9);
         StorageDead(_4);
         drop(_3) -> [return: bb3, unwind unreachable];
@@ -65,24 +71,20 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb4: {
         _7 = copy _4;
         StorageLive(_8);
-        _8 = <u32 as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind unreachable];
-    }
-
-    bb5: {
+        _8 = AddUnchecked(copy _7, const 1_u32);
         _4 = move _8;
         StorageDead(_8);
         _9 = Option::<u32>::Some(copy _7);
         StorageDead(_6);
-        StorageDead(_7);
         _10 = copy ((_9 as Some).0: u32);
         StorageLive(_11);
         _11 = &_3;
         StorageLive(_12);
         _12 = (copy _10,);
-        _13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb6, unwind unreachable];
+        _13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind unreachable];
     }
 
-    bb6: {
+    bb5: {
         StorageDead(_12);
         StorageDead(_11);
         StorageDead(_9);
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index ded30a15520..699d8bc8fea 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -23,6 +23,14 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let _7: u32;
                 let mut _8: u32;
                 scope 6 {
+                    scope 8 (inlined <u32 as Step>::forward_unchecked) {
+                        scope 9 (inlined core::num::<impl u32>::unchecked_add) {
+                            scope 10 (inlined core::ub_checks::check_language_ub) {
+                                scope 11 (inlined core::ub_checks::check_language_ub::runtime) {
+                                }
+                            }
+                        }
+                    }
                 }
                 scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     let mut _5: u32;
@@ -41,7 +49,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
 
     bb1: {
         StorageLive(_9);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = copy _4;
@@ -52,7 +59,6 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
 
     bb2: {
         StorageDead(_6);
-        StorageDead(_7);
         StorageDead(_9);
         StorageDead(_4);
         drop(_3) -> [return: bb3, unwind continue];
@@ -65,35 +71,31 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     bb4: {
         _7 = copy _4;
         StorageLive(_8);
-        _8 = <u32 as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind: bb7];
-    }
-
-    bb5: {
+        _8 = AddUnchecked(copy _7, const 1_u32);
         _4 = move _8;
         StorageDead(_8);
         _9 = Option::<u32>::Some(copy _7);
         StorageDead(_6);
-        StorageDead(_7);
         _10 = copy ((_9 as Some).0: u32);
         StorageLive(_11);
         _11 = &_3;
         StorageLive(_12);
         _12 = (copy _10,);
-        _13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb7];
+        _13 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb6];
     }
 
-    bb6: {
+    bb5: {
         StorageDead(_12);
         StorageDead(_11);
         StorageDead(_9);
         goto -> bb1;
     }
 
-    bb7 (cleanup): {
-        drop(_3) -> [return: bb8, unwind terminate(cleanup)];
+    bb6 (cleanup): {
+        drop(_3) -> [return: bb7, unwind terminate(cleanup)];
     }
 
-    bb8 (cleanup): {
+    bb7 (cleanup): {
         resume;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
index 2621ec67531..f3033d4a2fa 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
@@ -9,6 +9,14 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let _5: u32;
             let mut _6: u32;
             scope 3 {
+                scope 5 (inlined <u32 as Step>::forward_unchecked) {
+                    scope 6 (inlined core::num::<impl u32>::unchecked_add) {
+                        scope 7 (inlined core::ub_checks::check_language_ub) {
+                            scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
+                            }
+                        }
+                    }
+                }
             }
             scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 let mut _2: u32;
@@ -18,7 +26,6 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
     }
 
     bb0: {
-        StorageLive(_5);
         StorageLive(_4);
         StorageLive(_2);
         _2 = copy ((*_1).0: u32);
@@ -32,25 +39,21 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
 
     bb1: {
         _0 = const Option::<u32>::None;
-        goto -> bb4;
+        goto -> bb3;
     }
 
     bb2: {
         _5 = copy ((*_1).0: u32);
         StorageLive(_6);
-        _6 = <u32 as Step>::forward_unchecked(copy _5, const 1_usize) -> [return: bb3, unwind unreachable];
-    }
-
-    bb3: {
+        _6 = AddUnchecked(copy _5, const 1_u32);
         ((*_1).0: u32) = move _6;
         StorageDead(_6);
         _0 = Option::<u32>::Some(copy _5);
-        goto -> bb4;
+        goto -> bb3;
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_4);
-        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
index 338fb4b9523..f3033d4a2fa 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
@@ -9,6 +9,14 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let _5: u32;
             let mut _6: u32;
             scope 3 {
+                scope 5 (inlined <u32 as Step>::forward_unchecked) {
+                    scope 6 (inlined core::num::<impl u32>::unchecked_add) {
+                        scope 7 (inlined core::ub_checks::check_language_ub) {
+                            scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
+                            }
+                        }
+                    }
+                }
             }
             scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 let mut _2: u32;
@@ -18,7 +26,6 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
     }
 
     bb0: {
-        StorageLive(_5);
         StorageLive(_4);
         StorageLive(_2);
         _2 = copy ((*_1).0: u32);
@@ -32,25 +39,21 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
 
     bb1: {
         _0 = const Option::<u32>::None;
-        goto -> bb4;
+        goto -> bb3;
     }
 
     bb2: {
         _5 = copy ((*_1).0: u32);
         StorageLive(_6);
-        _6 = <u32 as Step>::forward_unchecked(copy _5, const 1_usize) -> [return: bb3, unwind continue];
-    }
-
-    bb3: {
+        _6 = AddUnchecked(copy _5, const 1_u32);
         ((*_1).0: u32) = move _6;
         StorageDead(_6);
         _0 = Option::<u32>::Some(copy _5);
-        goto -> bb4;
+        goto -> bb3;
     }
 
-    bb4: {
+    bb3: {
         StorageDead(_4);
-        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index 151783969dd..f8d11df5185 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -28,6 +28,14 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: usize;
                 let mut _8: usize;
                 scope 7 {
+                    scope 9 (inlined <usize as Step>::forward_unchecked) {
+                        scope 10 (inlined core::num::<impl usize>::unchecked_add) {
+                            scope 11 (inlined core::ub_checks::check_language_ub) {
+                                scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                                }
+                            }
+                        }
+                    }
                 }
                 scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     let mut _5: usize;
@@ -47,7 +55,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
 
     bb1: {
         StorageLive(_9);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = copy _4;
@@ -58,7 +65,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
 
     bb2: {
         StorageDead(_6);
-        StorageDead(_7);
         StorageDead(_9);
         StorageDead(_4);
         drop(_2) -> [return: bb3, unwind unreachable];
@@ -71,30 +77,26 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     bb4: {
         _7 = copy _4;
         StorageLive(_8);
-        _8 = <usize as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind unreachable];
-    }
-
-    bb5: {
+        _8 = AddUnchecked(copy _7, const 1_usize);
         _4 = move _8;
         StorageDead(_8);
         _9 = Option::<usize>::Some(copy _7);
         StorageDead(_6);
-        StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
         _11 = Lt(copy _10, copy _3);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable];
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind unreachable];
     }
 
-    bb6: {
+    bb5: {
         _12 = &(*_1)[_10];
         StorageLive(_13);
         _13 = &_2;
         StorageLive(_14);
         _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb6, unwind unreachable];
     }
 
-    bb7: {
+    bb6: {
         StorageDead(_14);
         StorageDead(_13);
         StorageDead(_9);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 006329dc20d..2c249197894 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -28,6 +28,14 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: usize;
                 let mut _8: usize;
                 scope 7 {
+                    scope 9 (inlined <usize as Step>::forward_unchecked) {
+                        scope 10 (inlined core::num::<impl usize>::unchecked_add) {
+                            scope 11 (inlined core::ub_checks::check_language_ub) {
+                                scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                                }
+                            }
+                        }
+                    }
                 }
                 scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     let mut _5: usize;
@@ -47,7 +55,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
 
     bb1: {
         StorageLive(_9);
-        StorageLive(_7);
         StorageLive(_6);
         StorageLive(_5);
         _5 = copy _4;
@@ -58,7 +65,6 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
 
     bb2: {
         StorageDead(_6);
-        StorageDead(_7);
         StorageDead(_9);
         StorageDead(_4);
         drop(_2) -> [return: bb3, unwind continue];
@@ -71,41 +77,37 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     bb4: {
         _7 = copy _4;
         StorageLive(_8);
-        _8 = <usize as Step>::forward_unchecked(copy _7, const 1_usize) -> [return: bb5, unwind: bb8];
-    }
-
-    bb5: {
+        _8 = AddUnchecked(copy _7, const 1_usize);
         _4 = move _8;
         StorageDead(_8);
         _9 = Option::<usize>::Some(copy _7);
         StorageDead(_6);
-        StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
         _11 = Lt(copy _10, copy _3);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8];
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind: bb7];
     }
 
-    bb6: {
+    bb5: {
         _12 = &(*_1)[_10];
         StorageLive(_13);
         _13 = &_2;
         StorageLive(_14);
         _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
+        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb6, unwind: bb7];
     }
 
-    bb7: {
+    bb6: {
         StorageDead(_14);
         StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
 
-    bb8 (cleanup): {
-        drop(_2) -> [return: bb9, unwind terminate(cleanup)];
+    bb7 (cleanup): {
+        drop(_2) -> [return: bb8, unwind terminate(cleanup)];
     }
 
-    bb9 (cleanup): {
+    bb8 (cleanup): {
         resume;
     }
 }
diff --git a/tests/pretty/hir-fn-params.pp b/tests/pretty/hir-fn-params.pp
new file mode 100644
index 00000000000..3799c8a3c3b
--- /dev/null
+++ b/tests/pretty/hir-fn-params.pp
@@ -0,0 +1,38 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-fn-params.pp
+
+// This tests the pretty-printing of various kinds of function parameters.
+
+//---------------------------------------------------------------------------
+// Normal functions and methods.
+
+fn normal_fn(_: u32, a: u32) { }
+
+struct S;
+impl S {
+    fn method(_: u32, a: u32) { }
+}
+
+//---------------------------------------------------------------------------
+// More exotic forms, which get a different pretty-printing path. In the past,
+// anonymous params and `_` params printed incorrectly, e.g. `fn(u32, _: u32)`
+// was printed as `fn(: u32, : u32)`.
+//
+// Ideally we would also test invalid patterns, e.g. `fn(1: u32, &a: u32)`,
+// because they had similar problems. But the pretty-printing tests currently
+// can't contain compile errors.
+
+fn bare_fn(x: fn(u32, _: u32, a: u32)) { }
+
+extern "C" {
+    unsafe fn foreign_fn(_: u32, a: u32);
+}
+
+trait T {
+    fn trait_fn(u32, _: u32, a: u32);
+}
diff --git a/tests/pretty/hir-fn-params.rs b/tests/pretty/hir-fn-params.rs
new file mode 100644
index 00000000000..5ace5289d08
--- /dev/null
+++ b/tests/pretty/hir-fn-params.rs
@@ -0,0 +1,34 @@
+//@ pretty-compare-only
+//@ pretty-mode:hir
+//@ pp-exact:hir-fn-params.pp
+
+// This tests the pretty-printing of various kinds of function parameters.
+
+//---------------------------------------------------------------------------
+// Normal functions and methods.
+
+fn normal_fn(_: u32, a: u32) {}
+
+struct S;
+impl S {
+    fn method(_: u32, a: u32) {}
+}
+
+//---------------------------------------------------------------------------
+// More exotic forms, which get a different pretty-printing path. In the past,
+// anonymous params and `_` params printed incorrectly, e.g. `fn(u32, _: u32)`
+// was printed as `fn(: u32, : u32)`.
+//
+// Ideally we would also test invalid patterns, e.g. `fn(1: u32, &a: u32)`,
+// because they had similar problems. But the pretty-printing tests currently
+// can't contain compile errors.
+
+fn bare_fn(x: fn(u32, _: u32, a: u32)) {}
+
+extern "C" {
+    fn foreign_fn(_: u32, a: u32);
+}
+
+trait T {
+    fn trait_fn(u32, _: u32, a: u32);
+}
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 01d90717107..64e65ece85d 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -40,6 +40,7 @@
 //@ revisions: loongarch64
 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64] needs-llvm-components: loongarch
+//@[loongarch64] min-llvm-version: 20
 //FIXME: wasm is disabled due to <https://github.com/rust-lang/rust/issues/115666>.
 //FIXME @ revisions: wasm
 //FIXME @[wasm] compile-flags: --target wasm32-unknown-unknown
diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
index 0e544119650..c88f3af7642 100644
--- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
+++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
@@ -1,35 +1,35 @@
 error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:22:18
+  --> $DIR/bad-reg.rs:23:18
    |
 LL |         asm!("", out("$r0") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$tp`: reserved for TLS
-  --> $DIR/bad-reg.rs:24:18
+  --> $DIR/bad-reg.rs:25:18
    |
 LL |         asm!("", out("$tp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:26:18
+  --> $DIR/bad-reg.rs:27:18
    |
 LL |         asm!("", out("$sp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$r21`: reserved by the ABI
-  --> $DIR/bad-reg.rs:28:18
+  --> $DIR/bad-reg.rs:29:18
    |
 LL |         asm!("", out("$r21") _);
    |                  ^^^^^^^^^^^^^
 
 error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:30:18
+  --> $DIR/bad-reg.rs:31:18
    |
 LL |         asm!("", out("$fp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:32:18
+  --> $DIR/bad-reg.rs:33:18
    |
 LL |         asm!("", out("$r31") _);
    |                  ^^^^^^^^^^^^^
diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
index 6d0410dc6a1..cb8e55a9722 100644
--- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
+++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
@@ -1,59 +1,59 @@
 error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:22:18
+  --> $DIR/bad-reg.rs:23:18
    |
 LL |         asm!("", out("$r0") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$tp`: reserved for TLS
-  --> $DIR/bad-reg.rs:24:18
+  --> $DIR/bad-reg.rs:25:18
    |
 LL |         asm!("", out("$tp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:26:18
+  --> $DIR/bad-reg.rs:27:18
    |
 LL |         asm!("", out("$sp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$r21`: reserved by the ABI
-  --> $DIR/bad-reg.rs:28:18
+  --> $DIR/bad-reg.rs:29:18
    |
 LL |         asm!("", out("$r21") _);
    |                  ^^^^^^^^^^^^^
 
 error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:30:18
+  --> $DIR/bad-reg.rs:31:18
    |
 LL |         asm!("", out("$fp") _);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:32:18
+  --> $DIR/bad-reg.rs:33:18
    |
 LL |         asm!("", out("$r31") _);
    |                  ^^^^^^^^^^^^^
 
 error: register class `freg` requires at least one of the following target features: d, f
-  --> $DIR/bad-reg.rs:36:26
+  --> $DIR/bad-reg.rs:37:26
    |
 LL |         asm!("/* {} */", in(freg) f);
    |                          ^^^^^^^^^^
 
 error: register class `freg` requires at least one of the following target features: d, f
-  --> $DIR/bad-reg.rs:38:26
+  --> $DIR/bad-reg.rs:39:26
    |
 LL |         asm!("/* {} */", out(freg) _);
    |                          ^^^^^^^^^^^
 
 error: register class `freg` requires at least one of the following target features: d, f
-  --> $DIR/bad-reg.rs:40:26
+  --> $DIR/bad-reg.rs:41:26
    |
 LL |         asm!("/* {} */", in(freg) d);
    |                          ^^^^^^^^^^
 
 error: register class `freg` requires at least one of the following target features: d, f
-  --> $DIR/bad-reg.rs:42:26
+  --> $DIR/bad-reg.rs:43:26
    |
 LL |         asm!("/* {} */", out(freg) d);
    |                          ^^^^^^^^^^^
diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs
index 685b460bc92..db1c778e5a2 100644
--- a/tests/ui/asm/loongarch/bad-reg.rs
+++ b/tests/ui/asm/loongarch/bad-reg.rs
@@ -1,6 +1,7 @@
 //@ add-core-stubs
 //@ needs-asm-support
 //@ revisions: loongarch64_lp64d loongarch64_lp64s
+//@ min-llvm-version: 20
 //@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64_lp64d] needs-llvm-components: loongarch
 //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
index 0a31cc67533..459f3ea1642 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
@@ -15,6 +15,10 @@ note: required by a bound in `is_send`
    |
 LL | fn is_send(_: impl Send) {}
    |                    ^^^^ required by this bound in `is_send`
+help: consider further restricting the associated type
+   |
+LL | >() where <T as Foo>::method(..): Send {
+   |     ++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/associated-type-bounds/return-type-notation/display.stderr b/tests/ui/associated-type-bounds/return-type-notation/display.stderr
index b895d796952..a614089ce40 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/display.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/display.stderr
@@ -11,6 +11,10 @@ note: required by a bound in `needs_trait`
    |
 LL | fn needs_trait(_: impl Trait) {}
    |                        ^^^^^ required by this bound in `needs_trait`
+help: consider further restricting the associated type
+   |
+LL | fn foo<T: Assoc>(t: T) where <T as Assoc>::method(..): Trait {
+   |                        +++++++++++++++++++++++++++++++++++++
 
 error[E0277]: the trait bound `impl Sized { <T as Assoc>::method_with_lt(..) }: Trait` is not satisfied
   --> $DIR/display.rs:16:17
@@ -25,6 +29,10 @@ note: required by a bound in `needs_trait`
    |
 LL | fn needs_trait(_: impl Trait) {}
    |                        ^^^^^ required by this bound in `needs_trait`
+help: consider further restricting the associated type
+   |
+LL | fn foo<T: Assoc>(t: T) where <T as Assoc>::method_with_lt(..): Trait {
+   |                        +++++++++++++++++++++++++++++++++++++++++++++
 
 error[E0277]: the trait bound `impl Sized: Trait` is not satisfied
   --> $DIR/display.rs:18:17
diff --git a/tests/ui/associated-type-bounds/return-type-notation/rendering.fixed b/tests/ui/associated-type-bounds/return-type-notation/rendering.fixed
new file mode 100644
index 00000000000..72c174a0ca0
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/rendering.fixed
@@ -0,0 +1,15 @@
+//@ run-rustfix
+
+#![allow(unused)]
+#![feature(return_type_notation)]
+
+trait Foo {
+    fn missing() -> impl Sized;
+}
+
+impl Foo for () {
+    //~^ ERROR not all trait items implemented, missing: `missing`
+fn missing() -> impl Sized { todo!() }
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/rendering.rs b/tests/ui/associated-type-bounds/return-type-notation/rendering.rs
new file mode 100644
index 00000000000..4c9948d4c06
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/rendering.rs
@@ -0,0 +1,14 @@
+//@ run-rustfix
+
+#![allow(unused)]
+#![feature(return_type_notation)]
+
+trait Foo {
+    fn missing() -> impl Sized;
+}
+
+impl Foo for () {
+    //~^ ERROR not all trait items implemented, missing: `missing`
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/rendering.stderr b/tests/ui/associated-type-bounds/return-type-notation/rendering.stderr
new file mode 100644
index 00000000000..62fdeb059dd
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/rendering.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `missing`
+  --> $DIR/rendering.rs:10:1
+   |
+LL |     fn missing() -> impl Sized;
+   |     --------------------------- `missing` from trait
+...
+LL | impl Foo for () {
+   | ^^^^^^^^^^^^^^^ missing `missing` in implementation
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap.rs b/tests/ui/cast/ptr-to-trait-obj-wrap.rs
index 6f9f6bddb99..9809ea80f95 100644
--- a/tests/ui/cast/ptr-to-trait-obj-wrap.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-wrap.rs
@@ -2,7 +2,6 @@
 // work. Note that the metadata doesn't change when a DST is wrapped in a
 // structure, so these casts *are* fine.
 //
-// `unwrap` and `unwrap_nested` currently don't work due to a compiler limitation.
 //@ check-pass
 
 trait A {}
diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr
index 5b82d3f539f..a9d67481ba1 100644
--- a/tests/ui/check-cfg/target_feature.stderr
+++ b/tests/ui/check-cfg/target_feature.stderr
@@ -60,6 +60,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `d32`
 `deflate-conversion`
 `dit`
+`div32`
 `doloop`
 `dotprod`
 `dpb`
@@ -133,8 +134,11 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `jsconv`
 `kl`
 `lahfsahf`
+`lam-bh`
+`lamcas`
 `lasx`
 `lbt`
+`ld-seq-sa`
 `leoncasa`
 `lor`
 `lse`
@@ -190,6 +194,7 @@ LL |     cfg!(target_feature = "_UNEXPECTED_VALUE");
 `reserve-x18`
 `rtm`
 `sb`
+`scq`
 `sha`
 `sha2`
 `sha3`
diff --git a/tests/ui/crate_type_flag.rs b/tests/ui/crate_type_flag.rs
new file mode 100644
index 00000000000..4f3cfbae45d
--- /dev/null
+++ b/tests/ui/crate_type_flag.rs
@@ -0,0 +1,4 @@
+//@ compile-flags: --crate-type dynlib
+//@ error-pattern: unknown crate type: `dynlib`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
+
+fn main() {}
diff --git a/tests/ui/crate_type_flag.stderr b/tests/ui/crate_type_flag.stderr
new file mode 100644
index 00000000000..26a3e1fbd68
--- /dev/null
+++ b/tests/ui/crate_type_flag.stderr
@@ -0,0 +1,2 @@
+error: unknown crate type: `dynlib`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
+
diff --git a/tests/ui/delegation/foreign-fn.rs b/tests/ui/delegation/foreign-fn.rs
new file mode 100644
index 00000000000..1d221da29ce
--- /dev/null
+++ b/tests/ui/delegation/foreign-fn.rs
@@ -0,0 +1,22 @@
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+#![deny(unsafe_op_in_unsafe_fn)]
+#![deny(unused_unsafe)]
+
+mod to_reuse {
+    unsafe extern "C" {
+        pub fn default_unsafe_foo();
+        pub unsafe fn unsafe_foo();
+        pub safe fn safe_foo();
+    }
+}
+
+reuse to_reuse::{default_unsafe_foo, unsafe_foo, safe_foo};
+
+fn main() {
+    let _: extern "C" fn() = default_unsafe_foo;
+    //~^ ERROR mismatched types
+    let _: extern "C" fn() = unsafe_foo;
+    //~^ ERROR mismatched types
+    let _: extern "C" fn() = safe_foo;
+}
diff --git a/tests/ui/delegation/foreign-fn.stderr b/tests/ui/delegation/foreign-fn.stderr
new file mode 100644
index 00000000000..f7d3dba4bb1
--- /dev/null
+++ b/tests/ui/delegation/foreign-fn.stderr
@@ -0,0 +1,27 @@
+error[E0308]: mismatched types
+  --> $DIR/foreign-fn.rs:17:30
+   |
+LL |     let _: extern "C" fn() = default_unsafe_foo;
+   |            ---------------   ^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn
+   |            |
+   |            expected due to this
+   |
+   = note: expected fn pointer `extern "C" fn()`
+                 found fn item `unsafe extern "C" fn() {default_unsafe_foo}`
+   = note: unsafe functions cannot be coerced into safe function pointers
+
+error[E0308]: mismatched types
+  --> $DIR/foreign-fn.rs:19:30
+   |
+LL |     let _: extern "C" fn() = unsafe_foo;
+   |            ---------------   ^^^^^^^^^^ expected safe fn, found unsafe fn
+   |            |
+   |            expected due to this
+   |
+   = note: expected fn pointer `extern "C" fn()`
+                 found fn item `unsafe extern "C" fn() {unsafe_foo}`
+   = note: unsafe functions cannot be coerced into safe function pointers
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr
index 0f8772024df..4ab816d30f6 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr
@@ -1,2 +1,2 @@
-error: unknown crate type: ``
+error: unknown crate type: ``, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
 
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr
index a4a97416996..91cc66801f1 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr
@@ -1,2 +1,2 @@
-error: unknown crate type: `proc_macro`
+error: unknown crate type: `proc_macro`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
 
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/invalid-compile-flags/crate-type-flag.rs
index 07d853b3307..01014307149 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.rs
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.rs
@@ -45,16 +45,16 @@
 // `proc-macro` is accepted, but `proc_macro` is not.
 //@ revisions: proc_underscore_macro
 //@[proc_underscore_macro] compile-flags: --crate-type=proc_macro
-//@[proc_underscore_macro] error-pattern: "unknown crate type: `proc_macro`"
+//@[proc_underscore_macro] error-pattern: unknown crate type: `proc_macro`
 
 // Empty `--crate-type` not accepted.
 //@ revisions: empty_crate_type
 //@[empty_crate_type] compile-flags: --crate-type=
-//@[empty_crate_type] error-pattern: "unknown crate type: ``"
+//@[empty_crate_type] error-pattern: unknown crate type: ``
 
 // Random unknown crate type. Also check that we can handle non-ASCII.
 //@ revisions: unknown
 //@[unknown] compile-flags: --crate-type=🤡
-//@[unknown] error-pattern: "unknown crate type: `🤡`"
+//@[unknown] error-pattern: unknown crate type: `🤡`
 
 fn main() {}
diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr
index 7fb0f09a1af..ec202e171f0 100644
--- a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr
+++ b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr
@@ -1,2 +1,2 @@
-error: unknown crate type: `🤡`
+error: unknown crate type: `🤡`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`
 
diff --git a/tests/ui/lint/unused/unused-field-in-pat-field.rs b/tests/ui/lint/unused/unused-field-in-pat-field.rs
new file mode 100644
index 00000000000..34959a1023f
--- /dev/null
+++ b/tests/ui/lint/unused/unused-field-in-pat-field.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+
+// Ensure we collect lint levels from pat fields in structs.
+
+#![deny(unused_variables)]
+
+pub struct Foo {
+    bar: u32,
+    baz: u32,
+}
+
+pub fn test(foo: Foo) {
+    let Foo {
+        #[allow(unused_variables)]
+        bar,
+        #[allow(unused_variables)]
+        baz,
+    } = foo;
+}
+
+fn main() {}
diff --git a/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr b/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr
index 41cd4fb93fa..cdd36ba4cae 100644
--- a/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr
+++ b/tests/ui/parser/shebang/issue-71471-ignore-tidy.stderr
@@ -3,6 +3,9 @@ error: expected `[`, found `B`
    |
 LL | #!B
    |   ^ expected `[`
+   |
+   = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not
+   = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/shebang/shebang-must-start-file.stderr b/tests/ui/parser/shebang/shebang-must-start-file.stderr
index 56991c96b7a..cf897d07780 100644
--- a/tests/ui/parser/shebang/shebang-must-start-file.stderr
+++ b/tests/ui/parser/shebang/shebang-must-start-file.stderr
@@ -3,6 +3,9 @@ error: expected `[`, found `/`
    |
 LL | #!/bin/bash
    |   ^ expected `[`
+   |
+   = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not
+   = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/shebang/shebang-split.rs b/tests/ui/parser/shebang/shebang-split.rs
new file mode 100644
index 00000000000..470bb669143
--- /dev/null
+++ b/tests/ui/parser/shebang/shebang-split.rs
@@ -0,0 +1,5 @@
+// empty line
+# !/bin/env
+
+// checks that diagnostics for shebang lookalikes is not present
+//@ error-pattern: expected `[`\n\n
diff --git a/tests/ui/parser/shebang/shebang-split.stderr b/tests/ui/parser/shebang/shebang-split.stderr
new file mode 100644
index 00000000000..804df1f0086
--- /dev/null
+++ b/tests/ui/parser/shebang/shebang-split.stderr
@@ -0,0 +1,8 @@
+error: expected `[`, found `/`
+  --> $DIR/shebang-split.rs:2:4
+   |
+LL | # !/bin/env
+   |    ^ expected `[`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.rs b/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.rs
new file mode 100644
index 00000000000..b951c6d92ee
--- /dev/null
+++ b/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+struct Point {
+    #[deprecated = "x is deprecated"]
+    _x: i32,
+    _y: i32,
+}
+
+fn main() {
+    let p = Point { _x: 1, _y: 2 }; //~ WARNING use of deprecated field `Point::_x`
+    // Before fix, it report an warning
+    let Point { #[expect(deprecated)]_x, .. } = p;
+}
diff --git a/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.stderr b/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.stderr
new file mode 100644
index 00000000000..707eb58e547
--- /dev/null
+++ b/tests/ui/pattern/check-struct-pat-fields-stability-issue-138319.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated field `Point::_x`: x is deprecated
+  --> $DIR/check-struct-pat-fields-stability-issue-138319.rs:9:21
+   |
+LL |     let p = Point { _x: 1, _y: 2 };
+   |                     ^^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs b/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs
new file mode 100644
index 00000000000..e1a37b9c65f
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/dont-ice-on-slice-in-deref-pat-in-closure.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//! Regression test for ICE in `rustc_hir_typeck::expr_use_visitor` on nesting a slice pattern
+//! inside a deref pattern inside a closure: rust-lang/rust#125059
+
+#![feature(deref_patterns)]
+#![allow(incomplete_features, unused)]
+
+fn simple_vec(vec: Vec<u32>) -> u32 {
+   (|| match Vec::<u32>::new() {
+        deref!([]) => 100,
+        _ => 2000,
+    })()
+}
+
+fn main() {}
diff --git a/tests/ui/stability-attribute/check-stability-issue-138319.rs b/tests/ui/stability-attribute/check-stability-issue-138319.rs
new file mode 100644
index 00000000000..5440e0cad94
--- /dev/null
+++ b/tests/ui/stability-attribute/check-stability-issue-138319.rs
@@ -0,0 +1,39 @@
+//@ check-pass
+fn _foo() {
+    _Bar { //~ WARNING use of deprecated struct `_Bar`: reason
+        #[expect(deprecated)]
+        foo: 0,
+    };
+}
+
+#[deprecated = "reason"]
+struct _Bar {
+    foo: u32,
+}
+
+fn _foo2() {
+    #[expect(deprecated)]
+    _Bar2 {
+        foo2: 0,
+    };
+}
+
+#[deprecated = "reason"]
+struct _Bar2 {
+    foo2: u32,
+}
+
+fn _foo3() {
+    _Bar3 {
+        #[expect(deprecated)]
+        foo3: 0,
+    };
+}
+
+struct _Bar3 {
+    #[deprecated = "reason"]
+    foo3: u32,
+}
+
+
+fn main() {}
diff --git a/tests/ui/stability-attribute/check-stability-issue-138319.stderr b/tests/ui/stability-attribute/check-stability-issue-138319.stderr
new file mode 100644
index 00000000000..4a2c3554a1e
--- /dev/null
+++ b/tests/ui/stability-attribute/check-stability-issue-138319.stderr
@@ -0,0 +1,10 @@
+warning: use of deprecated struct `_Bar`: reason
+  --> $DIR/check-stability-issue-138319.rs:3:5
+   |
+LL |     _Bar {
+   |     ^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/typeck/cyclic_type_ice.stderr b/tests/ui/typeck/cyclic_type_ice.stderr
index 4dc02a53c02..645766becbf 100644
--- a/tests/ui/typeck/cyclic_type_ice.stderr
+++ b/tests/ui/typeck/cyclic_type_ice.stderr
@@ -23,7 +23,7 @@ LL |     let f = |_, _| ();
 help: provide the argument
    |
 LL -     f(f);
-LL +     f(/*  */, /*  */);
+LL +     f(/* _ */, /* _ */);
    |
 
 error: aborting due to 2 previous errors
diff --git a/triagebot.toml b/triagebot.toml
index 84aae8a5179..0096b22da17 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1081,6 +1081,7 @@ warn_non_default_branch.enable = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
+    "ChrisDenton",
 ]
 
 [[assign.warn_non_default_branch.exceptions]]
@@ -1115,7 +1116,6 @@ compiler = [
     "@wesleywiser",
 ]
 libs = [
-    "@cuviper",
     "@Mark-Simulacrum",
     "@Amanieu",
     "@Noratrieb",