about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOli Scherer <github35764891676564198441@oli-obk.de>2025-07-22 07:31:34 +0000
committerGitHub <noreply@github.com>2025-07-22 07:31:34 +0000
commit7a8288bce479b12f489a2b66b5cee1dfc6ff2e07 (patch)
tree1e3358af6a7e888bc61e10260096da0fad04ade5 /src
parent800d80593e807371a7a149655b1625c70e3a9416 (diff)
parent4d62686f4f3d5249e96c0ae82217abae052fe481 (diff)
Merge pull request #4487 from rust-lang/rustup-2025-07-22
Automatic Rustup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs195
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs44
-rw-r--r--src/bootstrap/src/core/builder/tests.rs8
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/building/suggested.md2
-rw-r--r--src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md4
-rw-r--r--src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md2
-rw-r--r--src/doc/rustc-dev-guide/src/serialization.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md2
-rw-r--r--src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/offload.md8
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.lock1
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.toml1
-rw-r--r--src/tools/clippy/tests/compile-test.rs29
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs3
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.stderr8
-rw-r--r--src/tools/clippy/tests/ui/iter_over_hash_type.rs11
-rw-r--r--src/tools/clippy/tests/ui/iter_over_hash_type.stderr26
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.rs2
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.stderr14
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed2
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs2
m---------src/tools/enzyme0
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs58
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs2
-rw-r--r--src/tools/miri/tests/pass/fn_align.rs10
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs22
-rw-r--r--src/tools/opt-dist/src/environment.rs2
-rw-r--r--src/tools/opt-dist/src/exec.rs4
-rw-r--r--src/tools/opt-dist/src/main.rs16
-rw-r--r--src/tools/opt-dist/src/tests.rs2
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs9
-rw-r--r--src/tools/rust-analyzer/Cargo.lock41
-rw-r--r--src/tools/rust-analyzer/Cargo.toml8
-rw-r--r--src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs14
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs48
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs66
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs37
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs9
-rwxr-xr-xsrc/tools/rust-analyzer/crates/ide/src/folding_ranges.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/references.rs38
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs1
-rw-r--r--src/tools/rust-analyzer/crates/tt/src/iter.rs11
-rw-r--r--src/tools/rust-analyzer/rust-version2
50 files changed, 523 insertions, 288 deletions
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index f0acb7f7141..cfe090b22dc 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -370,132 +370,18 @@ impl Step for CodegenBackend {
     }
 }
 
-/// Checks Rust analyzer that links to .rmetas from a checked rustc.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RustAnalyzer {
-    pub build_compiler: Compiler,
-    pub target: TargetSelection,
-}
-
-impl Step for RustAnalyzer {
-    type Output = ();
-    const ONLY_HOSTS: bool = true;
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let builder = run.builder;
-        run.path("src/tools/rust-analyzer").default_condition(
-            builder
-                .config
-                .tools
-                .as_ref()
-                .is_none_or(|tools| tools.iter().any(|tool| tool == "rust-analyzer")),
-        )
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        let build_compiler = prepare_compiler_for_check(run.builder, run.target, Mode::ToolRustc);
-        run.builder.ensure(RustAnalyzer { build_compiler, target: run.target });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        let build_compiler = self.build_compiler;
-        let target = self.target;
-
-        let mut cargo = prepare_tool_cargo(
-            builder,
-            build_compiler,
-            Mode::ToolRustc,
-            target,
-            builder.kind,
-            "src/tools/rust-analyzer",
-            SourceType::InTree,
-            &["in-rust-tree".to_owned()],
-        );
-
-        cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES);
-
-        cargo.arg("--bins");
-        cargo.arg("--tests");
-        cargo.arg("--benches");
-
-        // Cargo's output path in a given stage, compiled by a particular
-        // compiler for the specified target.
-        let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::ToolRustc, target))
-            .with_prefix("rust-analyzer-check");
-
-        let _guard = builder.msg_check("rust-analyzer artifacts", target, None);
-        run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
-    }
-
-    fn metadata(&self) -> Option<StepMetadata> {
-        Some(StepMetadata::check("rust-analyzer", self.target).built_by(self.build_compiler))
-    }
-}
-
-/// Compiletest is implicitly "checked" when it gets built in order to run tests,
-/// so this is mainly for people working on compiletest to run locally.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Compiletest {
-    pub target: TargetSelection,
-}
-
-impl Step for Compiletest {
-    type Output = ();
-    const ONLY_HOSTS: bool = true;
-    const DEFAULT: bool = false;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/compiletest")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Compiletest { target: run.target });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        let mode = if builder.config.compiletest_use_stage0_libtest {
-            Mode::ToolBootstrap
-        } else {
-            Mode::ToolStd
-        };
-        let build_compiler = prepare_compiler_for_check(builder, self.target, mode);
-
-        let mut cargo = prepare_tool_cargo(
-            builder,
-            build_compiler,
-            mode,
-            self.target,
-            builder.kind,
-            "src/tools/compiletest",
-            SourceType::InTree,
-            &[],
-        );
-
-        cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
-
-        cargo.arg("--all-targets");
-
-        let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, self.target))
-            .with_prefix("compiletest-check");
-
-        let _guard = builder.msg_check("compiletest artifacts", self.target, None);
-        run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
-    }
-
-    fn metadata(&self) -> Option<StepMetadata> {
-        Some(StepMetadata::check("compiletest", self.target))
-    }
-}
-
 macro_rules! tool_check_step {
     (
         $name:ident {
             // The part of this path after the final '/' is also used as a display name.
             path: $path:literal
             $(, alt_path: $alt_path:literal )*
-            , mode: $mode:path
+            // Closure that returns `Mode` based on the passed `&Builder<'_>`
+            , mode: $mode:expr
+            // Subset of nightly features that are allowed to be used when checking
             $(, allow_features: $allow_features:expr )?
+            // Features that should be enabled when checking
+            $(, enable_features: [$($enable_features:expr),*] )?
             $(, default: $default:literal )?
             $( , )?
         }
@@ -518,10 +404,13 @@ macro_rules! tool_check_step {
 
             fn make_run(run: RunConfig<'_>) {
                 let target = run.target;
-                let build_compiler = prepare_compiler_for_check(run.builder, target, $mode);
+                let builder = run.builder;
+                let mode = $mode(builder);
+
+                let build_compiler = prepare_compiler_for_check(run.builder, target, mode);
 
                 // It doesn't make sense to cross-check bootstrap tools
-                if $mode == Mode::ToolBootstrap && target != run.builder.host_target {
+                if mode == Mode::ToolBootstrap && target != run.builder.host_target {
                     println!("WARNING: not checking bootstrap tool {} for target {target} as it is a bootstrap (host-only) tool", stringify!($path));
                     return;
                 };
@@ -536,7 +425,9 @@ macro_rules! tool_check_step {
                     $( _value = $allow_features; )?
                     _value
                 };
-                run_tool_check_step(builder, build_compiler, target, $path, $mode, allow_features);
+                let extra_features: &[&str] = &[$($($enable_features),*)?];
+                let mode = $mode(builder);
+                run_tool_check_step(builder, build_compiler, target, $path, mode, allow_features, extra_features);
             }
 
             fn metadata(&self) -> Option<StepMetadata> {
@@ -554,9 +445,11 @@ fn run_tool_check_step(
     path: &str,
     mode: Mode,
     allow_features: &str,
+    extra_features: &[&str],
 ) {
     let display_name = path.rsplit('/').next().unwrap();
 
+    let extra_features = extra_features.iter().map(|f| f.to_string()).collect::<Vec<String>>();
     let mut cargo = prepare_tool_cargo(
         builder,
         build_compiler,
@@ -569,12 +462,19 @@ fn run_tool_check_step(
         // steps should probably be marked non-default so that the default
         // checks aren't affected by toolstate being broken.
         SourceType::InTree,
-        &[],
+        &extra_features,
     );
     cargo.allow_features(allow_features);
 
-    // FIXME: check bootstrap doesn't currently work with --all-targets
-    cargo.arg("--all-targets");
+    // FIXME: check bootstrap doesn't currently work when multiple targets are checked
+    // FIXME: rust-analyzer does not work with --all-targets
+    if display_name == "rust-analyzer" {
+        cargo.arg("--bins");
+        cargo.arg("--tests");
+        cargo.arg("--benches");
+    } else {
+        cargo.arg("--all-targets");
+    }
 
     let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target))
         .with_prefix(&format!("{display_name}-check"));
@@ -593,43 +493,66 @@ fn run_tool_check_step(
 tool_check_step!(Rustdoc {
     path: "src/tools/rustdoc",
     alt_path: "src/librustdoc",
-    mode: Mode::ToolRustc
+    mode: |_builder| Mode::ToolRustc
 });
 // Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
 // of a submodule. Since the SourceType only drives the deny-warnings
 // behavior, treat it as in-tree so that any new warnings in clippy will be
 // rejected.
-tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustc });
-tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustc });
-tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustc });
-tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustc });
+tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustc });
+tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustc });
+tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: |_builder| Mode::ToolRustc });
+tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustc });
+tool_check_step!(RustAnalyzer {
+    path: "src/tools/rust-analyzer",
+    mode: |_builder| Mode::ToolRustc,
+    allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
+    enable_features: ["in-rust-tree"],
+});
 tool_check_step!(MiroptTestTools {
     path: "src/tools/miropt-test-tools",
-    mode: Mode::ToolBootstrap
+    mode: |_builder| Mode::ToolBootstrap
 });
 // We want to test the local std
 tool_check_step!(TestFloatParse {
     path: "src/tools/test-float-parse",
-    mode: Mode::ToolStd,
+    mode: |_builder| Mode::ToolStd,
     allow_features: tool::TestFloatParse::ALLOW_FEATURES
 });
 tool_check_step!(FeaturesStatusDump {
     path: "src/tools/features-status-dump",
-    mode: Mode::ToolBootstrap
+    mode: |_builder| Mode::ToolBootstrap
 });
 
-tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
+tool_check_step!(Bootstrap {
+    path: "src/bootstrap",
+    mode: |_builder| Mode::ToolBootstrap,
+    default: false
+});
 
 // `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
 // check to make it easier to work on.
 tool_check_step!(RunMakeSupport {
     path: "src/tools/run-make-support",
-    mode: Mode::ToolBootstrap,
+    mode: |_builder| Mode::ToolBootstrap,
     default: false
 });
 
 tool_check_step!(CoverageDump {
     path: "src/tools/coverage-dump",
-    mode: Mode::ToolBootstrap,
+    mode: |_builder| Mode::ToolBootstrap,
     default: false
 });
+
+// Compiletest is implicitly "checked" when it gets built in order to run tests,
+// so this is mainly for people working on compiletest to run locally.
+tool_check_step!(Compiletest {
+    path: "src/tools/compiletest",
+    mode: |builder: &Builder<'_>| if builder.config.compiletest_use_stage0_libtest {
+        Mode::ToolBootstrap
+    } else {
+        Mode::ToolStd
+    },
+    allow_features: COMPILETEST_ALLOW_FEATURES,
+    default: false,
+});
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 7652ea1a488..8344b0e03b4 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -739,7 +739,6 @@ impl Step for CompiletestTest {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Clippy {
-    stage: u32,
     host: TargetSelection,
 }
 
@@ -753,33 +752,23 @@ impl Step for Clippy {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        // If stage is explicitly set or not lower than 2, keep it. Otherwise, make sure it's at least 2
-        // as tests for this step don't work with a lower stage.
-        let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 {
-            run.builder.top_stage
-        } else {
-            2
-        };
-
-        run.builder.ensure(Clippy { stage, host: run.target });
+        run.builder.ensure(Clippy { host: run.target });
     }
 
     /// Runs `cargo test` for clippy.
     fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
+        let stage = builder.top_stage;
         let host = self.host;
-        let compiler = builder.compiler(stage, host);
-
-        if stage < 2 {
-            eprintln!("WARNING: clippy tests on stage {stage} may not behave well.");
-            eprintln!("HELP: consider using stage 2");
-        }
+        // We need to carefully distinguish the compiler that builds clippy, and the compiler
+        // that is linked into the clippy being tested. `target_compiler` is the latter,
+        // and it must also be used by clippy's test runner to build tests and their dependencies.
+        let target_compiler = builder.compiler(stage, host);
 
-        let tool_result = builder.ensure(tool::Clippy { compiler, target: self.host });
-        let compiler = tool_result.build_compiler;
+        let tool_result = builder.ensure(tool::Clippy { compiler: target_compiler, target: host });
+        let tool_compiler = tool_result.build_compiler;
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            tool_compiler,
             Mode::ToolRustc,
             host,
             Kind::Test,
@@ -788,11 +777,17 @@ impl Step for Clippy {
             &[],
         );
 
-        cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
-        cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
-        let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
+        cargo.env("RUSTC_TEST_SUITE", builder.rustc(tool_compiler));
+        cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(tool_compiler));
+        let host_libs = builder.stage_out(tool_compiler, Mode::ToolRustc).join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
 
+        // Build the standard library that the tests can use.
+        builder.std(target_compiler, host);
+        cargo.env("TEST_SYSROOT", builder.sysroot(target_compiler));
+        cargo.env("TEST_RUSTC", builder.rustc(target_compiler));
+        cargo.env("TEST_RUSTC_LIB", builder.rustc_libdir(target_compiler));
+
         // Collect paths of tests to run
         'partially_test: {
             let paths = &builder.config.paths[..];
@@ -813,7 +808,8 @@ impl Step for Clippy {
         cargo.add_rustc_lib_path(builder);
         let cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
 
-        let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host);
+        let _guard =
+            builder.msg_sysroot_tool(Kind::Test, tool_compiler.stage, "clippy", host, host);
 
         // Clippy reports errors if it blessed the outputs
         if cargo.allow_failure().run(builder) {
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index e60a115b19d..c025a8b15d0 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1382,7 +1382,7 @@ mod snapshot {
         [check] rustc 1 <host> -> Miri 2 <target1>
         [check] rustc 1 <host> -> CargoMiri 2 <target1>
         [check] rustc 1 <host> -> Rustfmt 2 <target1>
-        [check] rustc 1 <host> -> rust-analyzer 2 <target1>
+        [check] rustc 1 <host> -> RustAnalyzer 2 <target1>
         [check] rustc 1 <host> -> TestFloatParse 2 <target1>
         [check] rustc 1 <host> -> std 1 <target1>
         ");
@@ -1530,7 +1530,7 @@ mod snapshot {
         insta::assert_snapshot!(
             ctx.config("check")
                 .path("compiletest")
-                .render_steps(), @"[check] compiletest <host>");
+                .render_steps(), @"[check] rustc 0 <host> -> Compiletest 1 <host>");
     }
 
     #[test]
@@ -1544,7 +1544,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
-        [check] compiletest <host>
+        [check] rustc 1 <host> -> Compiletest 2 <host>
         ");
     }
 
@@ -1569,7 +1569,7 @@ mod snapshot {
                 .path("rust-analyzer")
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> rust-analyzer 1 <host>
+        [check] rustc 0 <host> -> RustAnalyzer 1 <host>
         ");
     }
 
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index 3f10132b684..f6b7efe51a1 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-fd2eb391d032181459773f3498c17b198513e0d0
+460259d14de0274b97b8801e08cb2fe5f16fdac5
diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md
index 7f626314f71..c046161e77f 100644
--- a/src/doc/rustc-dev-guide/src/building/suggested.md
+++ b/src/doc/rustc-dev-guide/src/building/suggested.md
@@ -162,7 +162,7 @@ create a `.vim/coc-settings.json`. The settings can be edited with
 [`src/etc/rust_analyzer_settings.json`].
 
 Another way is without a plugin, and creating your own logic in your
-configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025):
+configuration. The following code will work for any checkout of rust-lang/rust (newer than February 2025):
 
 ```lua
 local function expand_config_variables(option)
diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md
index 709027883ae..d4f504ad2a9 100644
--- a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md
+++ b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md
@@ -38,7 +38,7 @@ Note that places 3 and 4 would never actually be possible to encounter as we alw
 This has a few failure modes:
 - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident.
 - People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident.
-- People may write visitors which check for `GenerArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`.
+- People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`.
 - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa).
 
 To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system:
@@ -60,4 +60,4 @@ This has a number of benefits:
 [ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html
 [visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty
 [visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg
-[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer
\ No newline at end of file
+[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer
diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
index 4f44cf1701c..3ec5ebd799e 100644
--- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
+++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-test-suite.md
@@ -20,7 +20,7 @@ Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck
 
 Directives to HtmlDocCk are assertions that place constraints on the generated HTML.
 They look similar to those given to `compiletest` in that they take the form of `//@` comments
-but ultimately, they are completey distinct and processed by different programs.
+but ultimately, they are completely distinct and processed by different programs.
 
 [XPath] is used to query parts of the HTML document tree.
 
diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md
index 47667061eda..8eb37bbe20b 100644
--- a/src/doc/rustc-dev-guide/src/serialization.md
+++ b/src/doc/rustc-dev-guide/src/serialization.md
@@ -75,7 +75,7 @@ impl<D: Decoder> Decodable<D> for MyStruct {
 
 rustc has a lot of [arena allocated types].
 Deserializing these types isn't possible without access to the arena that they need to be allocated on.
-The [`TyDecoder`] and [`TyEncoder`] traits are supertraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`].
+The [`TyDecoder`] and [`TyEncoder`] traits are subtraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`].
 
 Types which contain `arena` allocated types can then bound the type parameter of their
 [`Encodable`] and [`Decodable`] implementations with these traits.
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index ded30234e70..aa99347b2bb 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -29,7 +29,7 @@ on if or how to run the test, what behavior to expect, and more. See
 [directives](directives.md) and the test suite documentation below for more details
 on these annotations.
 
-See the [Adding new tests](adding.md) and [Best practies](best-practices.md)
+See the [Adding new tests](adding.md) and [Best practices](best-practices.md)
 chapters for a tutorial on creating a new test and advice on writing a good
 test, and the [Running tests](running.md) chapter on how to run the test suite.
 
diff --git a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md
index e3f091ca45f..0d1108c72e0 100644
--- a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md
+++ b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md
@@ -77,7 +77,7 @@ This end result is incorrect as we had two separate binders introducing their ow
 
 While in theory we could make this work it would be quite involved and more complex than the current setup, we would have to:
 - "rewrite" bound variables to have a higher `DebruijnIndex` whenever instantiating a `Binder`/`EarlyBinder` with a `Bound` ty/const/region 
-- When inferring an inference variable to a bound var, if that bound var is from a binder enterred after creating the infer var, we would have to lower the `DebruijnIndex` of the var.
+- When inferring an inference variable to a bound var, if that bound var is from a binder entered after creating the infer var, we would have to lower the `DebruijnIndex` of the var.
 - Separately track what binder an inference variable was created inside of, also what the innermost binder it can name parameters from (currently we only have to track the latter)
 - When resolving inference variables rewrite any bound variables according to the current binder depth of the infcx
 - Maybe more (while writing this list items kept getting added so it seems naive to think this is exhaustive)
diff --git a/src/doc/unstable-book/src/compiler-flags/offload.md b/src/doc/unstable-book/src/compiler-flags/offload.md
new file mode 100644
index 00000000000..4266e8c11a2
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/offload.md
@@ -0,0 +1,8 @@
+# `offload`
+
+The tracking issue for this feature is: [#131513](https://github.com/rust-lang/rust/issues/131513).
+
+------------------------
+
+This feature will later allow you to run functions on GPUs. It is work in progress.
+Set the `-Zoffload=Enable` compiler flag to experiment with it.
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.lock b/src/tools/clippy/clippy_test_deps/Cargo.lock
index a591dae3a1a..5be404f24e6 100644
--- a/src/tools/clippy/clippy_test_deps/Cargo.lock
+++ b/src/tools/clippy/clippy_test_deps/Cargo.lock
@@ -72,6 +72,7 @@ dependencies = [
  "futures",
  "if_chain",
  "itertools",
+ "libc",
  "parking_lot",
  "quote",
  "regex",
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml
index a23ffcaf2f9..fcedc5d4843 100644
--- a/src/tools/clippy/clippy_test_deps/Cargo.toml
+++ b/src/tools/clippy/clippy_test_deps/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
 # Add dependencies here to make them available in ui tests.
 
 [dependencies]
+libc = "0.2"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
 if_chain = "1.0"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 57d623b2cfc..83f91ccaa7b 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -151,7 +151,31 @@ impl TestContext {
         defaults.set_custom(
             "dependencies",
             DependencyBuilder {
-                program: CommandBuilder::cargo(),
+                program: {
+                    let mut p = CommandBuilder::cargo();
+                    // If we run in bootstrap, we need to use the right compiler for building the
+                    // tests -- not the compiler that built clippy, but the compiler that got linked
+                    // into clippy. Just invoking TEST_RUSTC does not work because LD_LIBRARY_PATH
+                    // is set in a way that makes it pick the wrong sysroot. Sadly due to
+                    // <https://github.com/rust-lang/cargo/issues/4423> we cannot use RUSTFLAGS to
+                    // set `--sysroot`, so we need to use bootstrap's rustc wrapper. That wrapper
+                    // however has some staging logic that is hurting us here, so to work around
+                    // that we set both the "real" and "staging" rustc to TEST_RUSTC, including the
+                    // associated library paths.
+                    if let Some(rustc) = option_env!("TEST_RUSTC") {
+                        let libdir = option_env!("TEST_RUSTC_LIB").unwrap();
+                        let sysroot = option_env!("TEST_SYSROOT").unwrap();
+                        p.envs.push(("RUSTC_REAL".into(), Some(rustc.into())));
+                        p.envs.push(("RUSTC_REAL_LIBDIR".into(), Some(libdir.into())));
+                        p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into())));
+                        p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into())));
+                        p.envs.push((
+                            "RUSTC_SYSROOT".into(),
+                            Some(sysroot.into()),
+                        ));
+                    }
+                    p
+                },
                 crate_manifest_path: Path::new("clippy_test_deps").join("Cargo.toml"),
                 build_std: None,
                 bless_lockfile: self.args.bless,
@@ -192,6 +216,9 @@ impl TestContext {
             let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
             config.program.args.push(dep.into());
         }
+        if let Some(sysroot) = option_env!("TEST_SYSROOT") {
+            config.program.args.push(format!("--sysroot={sysroot}").into());
+        }
 
         config.program.program = profile_path.join(if cfg!(windows) {
             "clippy-driver.exe"
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
index 5992d15935d..54650922871 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
@@ -16,7 +16,7 @@ pub fn derive(_: TokenStream) -> TokenStream {
     let output = quote! {
         // Should not trigger `useless_attribute`
         #[allow(dead_code)]
-        extern crate rustc_middle;
+        extern crate core;
     };
     output
 }
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index 5773ffddb91..ef667f5598a 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -1,6 +1,5 @@
 //! Test casts for alignment issues
 
-#![feature(rustc_private)]
 #![feature(core_intrinsics)]
 #![warn(clippy::cast_ptr_alignment)]
 #![allow(
@@ -10,8 +9,6 @@
     clippy::borrow_as_ptr
 )]
 
-extern crate libc;
-
 fn main() {
     /* These should be warned against */
 
diff --git a/src/tools/clippy/tests/ui/cast_alignment.stderr b/src/tools/clippy/tests/ui/cast_alignment.stderr
index 6d9a81f0ecf..ee4c3e9a77e 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.stderr
+++ b/src/tools/clippy/tests/ui/cast_alignment.stderr
@@ -1,5 +1,5 @@
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> tests/ui/cast_alignment.rs:19:5
+  --> tests/ui/cast_alignment.rs:16:5
    |
 LL |     (&1u8 as *const u8) as *const u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,19 +8,19 @@ LL |     (&1u8 as *const u8) as *const u16;
    = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]`
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> tests/ui/cast_alignment.rs:22:5
+  --> tests/ui/cast_alignment.rs:19:5
    |
 LL |     (&mut 1u8 as *mut u8) as *mut u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> tests/ui/cast_alignment.rs:26:5
+  --> tests/ui/cast_alignment.rs:23:5
    |
 LL |     (&1u8 as *const u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> tests/ui/cast_alignment.rs:29:5
+  --> tests/ui/cast_alignment.rs:26:5
    |
 LL |     (&mut 1u8 as *mut u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.rs b/src/tools/clippy/tests/ui/iter_over_hash_type.rs
index 914cc9df0de..9a3e7033cd8 100644
--- a/src/tools/clippy/tests/ui/iter_over_hash_type.rs
+++ b/src/tools/clippy/tests/ui/iter_over_hash_type.rs
@@ -3,15 +3,18 @@
 #![warn(clippy::iter_over_hash_type)]
 use std::collections::{HashMap, HashSet};
 
-extern crate rustc_data_structures;
-
 extern crate proc_macros;
 
+// Ensure it also works via type aliases (this isn't really the Fx hasher but that does not matter).
+type FxBuildHasher = std::collections::hash_map::RandomState;
+type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
+type FxHashSet<K> = HashSet<K, FxBuildHasher>;
+
 fn main() {
     let mut hash_set = HashSet::<i32>::new();
     let mut hash_map = HashMap::<i32, i32>::new();
-    let mut fx_hash_map = rustc_data_structures::fx::FxHashMap::<i32, i32>::default();
-    let mut fx_hash_set = rustc_data_structures::fx::FxHashMap::<i32, i32>::default();
+    let mut fx_hash_map = FxHashMap::<i32, i32>::default();
+    let mut fx_hash_set = FxHashSet::<i32>::default();
     let vec = Vec::<i32>::new();
 
     // test hashset
diff --git a/src/tools/clippy/tests/ui/iter_over_hash_type.stderr b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr
index 1bc6f4588d4..3356186547d 100644
--- a/src/tools/clippy/tests/ui/iter_over_hash_type.stderr
+++ b/src/tools/clippy/tests/ui/iter_over_hash_type.stderr
@@ -1,5 +1,5 @@
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:18:5
+  --> tests/ui/iter_over_hash_type.rs:21:5
    |
 LL | /     for x in &hash_set {
 LL | |
@@ -11,7 +11,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]`
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:22:5
+  --> tests/ui/iter_over_hash_type.rs:25:5
    |
 LL | /     for x in hash_set.iter() {
 LL | |
@@ -20,7 +20,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:26:5
+  --> tests/ui/iter_over_hash_type.rs:29:5
    |
 LL | /     for x in hash_set.clone() {
 LL | |
@@ -29,7 +29,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:30:5
+  --> tests/ui/iter_over_hash_type.rs:33:5
    |
 LL | /     for x in hash_set.drain() {
 LL | |
@@ -38,7 +38,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:36:5
+  --> tests/ui/iter_over_hash_type.rs:39:5
    |
 LL | /     for (x, y) in &hash_map {
 LL | |
@@ -47,7 +47,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:40:5
+  --> tests/ui/iter_over_hash_type.rs:43:5
    |
 LL | /     for x in hash_map.keys() {
 LL | |
@@ -56,7 +56,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:44:5
+  --> tests/ui/iter_over_hash_type.rs:47:5
    |
 LL | /     for x in hash_map.values() {
 LL | |
@@ -65,7 +65,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:48:5
+  --> tests/ui/iter_over_hash_type.rs:51:5
    |
 LL | /     for x in hash_map.values_mut() {
 LL | |
@@ -74,7 +74,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:52:5
+  --> tests/ui/iter_over_hash_type.rs:55:5
    |
 LL | /     for x in hash_map.iter() {
 LL | |
@@ -83,7 +83,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:56:5
+  --> tests/ui/iter_over_hash_type.rs:59:5
    |
 LL | /     for x in hash_map.clone() {
 LL | |
@@ -92,7 +92,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:60:5
+  --> tests/ui/iter_over_hash_type.rs:63:5
    |
 LL | /     for x in hash_map.drain() {
 LL | |
@@ -101,7 +101,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:66:5
+  --> tests/ui/iter_over_hash_type.rs:69:5
    |
 LL | /     for x in fx_hash_set {
 LL | |
@@ -110,7 +110,7 @@ LL | |     }
    | |_____^
 
 error: iteration over unordered hash-based type
-  --> tests/ui/iter_over_hash_type.rs:70:5
+  --> tests/ui/iter_over_hash_type.rs:73:5
    |
 LL | /     for x in fx_hash_map {
 LL | |
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
index 31ed1cf03a2..17c1b541f77 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
@@ -1,7 +1,5 @@
 #![warn(clippy::strlen_on_c_strings)]
 #![allow(dead_code, clippy::manual_c_str_literals)]
-#![feature(rustc_private)]
-extern crate libc;
 
 #[allow(unused)]
 use libc::strlen;
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
index 0f3798c9fd8..c641422f5df 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
@@ -1,7 +1,5 @@
 #![warn(clippy::strlen_on_c_strings)]
 #![allow(dead_code, clippy::manual_c_str_literals)]
-#![feature(rustc_private)]
-extern crate libc;
 
 #[allow(unused)]
 use libc::strlen;
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
index b8619fa2df3..84a93b99ee3 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.stderr
@@ -1,5 +1,5 @@
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:13:13
+  --> tests/ui/strlen_on_c_strings.rs:11:13
    |
 LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()`
@@ -8,37 +8,37 @@ LL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };
    = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:18:13
+  --> tests/ui/strlen_on_c_strings.rs:16:13
    |
 LL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:21:13
+  --> tests/ui/strlen_on_c_strings.rs:19:13
    |
 LL |     let _ = unsafe { strlen(cstr.as_ptr()) };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:25:22
+  --> tests/ui/strlen_on_c_strings.rs:23:22
    |
 LL |     let _ = unsafe { strlen((*pcstr).as_ptr()) };
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:31:22
+  --> tests/ui/strlen_on_c_strings.rs:29:22
    |
 LL |     let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:33:13
+  --> tests/ui/strlen_on_c_strings.rs:31:13
    |
 LL |     let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
 
 error: using `libc::strlen` on a `CString` or `CStr` value
-  --> tests/ui/strlen_on_c_strings.rs:37:22
+  --> tests/ui/strlen_on_c_strings.rs:35:22
    |
 LL |     let _ = unsafe { strlen(f(cstr).as_ptr()) };
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()`
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index a96c8f46f55..930bc1eaecf 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -13,7 +13,7 @@
 #[allow(unused_imports)]
 #[allow(unused_extern_crates)]
 #[macro_use]
-extern crate rustc_middle;
+extern crate regex as regex_crate;
 
 #[macro_use]
 extern crate proc_macro_derive;
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index b26410134bb..50fafd478e5 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -13,7 +13,7 @@
 #[allow(unused_imports)]
 #[allow(unused_extern_crates)]
 #[macro_use]
-extern crate rustc_middle;
+extern crate regex as regex_crate;
 
 #[macro_use]
 extern crate proc_macro_derive;
diff --git a/src/tools/enzyme b/src/tools/enzyme
-Subproject b5098d515d5e1bd0f5470553bc0d18da9794ca8
+Subproject 2cccfba93c1650f26f1cf8be8aa875a7c1d23fb
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index f6b7efe51a1..bd902ca1fd5 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-460259d14de0274b97b8801e08cb2fe5f16fdac5
+9748d87dc70a9a6725c5dbd76ce29d04752b4f90
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 10339928ac2..334503d2994 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -116,14 +116,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_ref();
         let info = this.get_alloc_info(alloc_id);
 
-        // Miri's address assignment leaks state across thread boundaries, which is incompatible
-        // with GenMC execution. So we instead let GenMC assign addresses to allocations.
-        if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
-            let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
-            return interp_ok(addr);
-        }
-
-        let mut rng = this.machine.rng.borrow_mut();
         // This is either called immediately after allocation (and then cached), or when
         // adjusting `tcx` pointers (which never get freed). So assert that we are looking
         // at a live allocation. This also ensures that we never re-assign an address to an
@@ -131,6 +123,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // information was removed.
         assert!(!matches!(info.kind, AllocKind::Dead));
 
+        // TypeId allocations always have a "base address" of 0 (i.e., the relative offset is the
+        // hash fragment and therefore equal to the actual integer value).
+        if matches!(info.kind, AllocKind::TypeId) {
+            return interp_ok(0);
+        }
+
+        // Miri's address assignment leaks state across thread boundaries, which is incompatible
+        // with GenMC execution. So we instead let GenMC assign addresses to allocations.
+        if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
+            let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
+            return interp_ok(addr);
+        }
+
         // This allocation does not have a base address yet, pick or reuse one.
         if !this.machine.native_lib.is_empty() {
             // In native lib mode, we use the "real" address of the bytes for this allocation.
@@ -157,7 +162,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         this.get_alloc_bytes_unchecked_raw(alloc_id)?
                     }
                 }
-                AllocKind::Function | AllocKind::Virtual => {
+                AllocKind::Function | AllocKind::VTable => {
                     // Allocate some dummy memory to get a unique address for this function/vtable.
                     let alloc_bytes = MiriAllocBytes::from_bytes(
                         &[0u8; 1],
@@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     std::mem::forget(alloc_bytes);
                     ptr
                 }
-                AllocKind::Dead => unreachable!(),
+                AllocKind::TypeId | AllocKind::Dead => unreachable!(),
             };
             // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
             return interp_ok(base_ptr.addr().to_u64());
         }
         // We are not in native lib mode, so we control the addresses ourselves.
+        let mut rng = this.machine.rng.borrow_mut();
         if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
             &mut *rng,
             info.size,
@@ -295,21 +301,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Store address in cache.
                 global_state.base_addr.try_insert(alloc_id, base_addr).unwrap();
 
-                // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it sorted.
-                // We have a fast-path for the common case that this address is bigger than all previous ones.
-                let pos = if global_state
-                    .int_to_ptr_map
-                    .last()
-                    .is_some_and(|(last_addr, _)| *last_addr < base_addr)
-                {
-                    global_state.int_to_ptr_map.len()
-                } else {
-                    global_state
+                // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it
+                // sorted. We have a fast-path for the common case that this address is bigger than
+                // all previous ones. We skip this for allocations at address 0; those can't be
+                // real, they must be TypeId "fake allocations".
+                if base_addr != 0 {
+                    let pos = if global_state
                         .int_to_ptr_map
-                        .binary_search_by_key(&base_addr, |(addr, _)| *addr)
-                        .unwrap_err()
-                };
-                global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
+                        .last()
+                        .is_some_and(|(last_addr, _)| *last_addr < base_addr)
+                    {
+                        global_state.int_to_ptr_map.len()
+                    } else {
+                        global_state
+                            .int_to_ptr_map
+                            .binary_search_by_key(&base_addr, |(addr, _)| *addr)
+                            .unwrap_err()
+                    };
+                    global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
+                }
 
                 interp_ok(base_addr)
             }
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index e834fdffdd1..2977efaae04 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -650,7 +650,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
                         dcx.log_protector();
                     }
                 },
-                AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
+                AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
                     // No stacked borrows on these allocations.
                 }
             }
@@ -1021,7 +1021,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
                 alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
             }
-            AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
+            AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
                 // No stacked borrows on these allocations.
             }
         }
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index aa92f8a8c30..ad2a67160f4 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -673,7 +673,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 trace!("Tree Borrows tag {tag:?} exposed in {alloc_id:?}");
                 alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag);
             }
-            AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
+            AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
                 // No tree borrows on these allocations.
             }
         }
diff --git a/src/tools/miri/tests/pass/fn_align.rs b/src/tools/miri/tests/pass/fn_align.rs
index 28f92995880..9752d033458 100644
--- a/src/tools/miri/tests/pass/fn_align.rs
+++ b/src/tools/miri/tests/pass/fn_align.rs
@@ -1,15 +1,19 @@
 //@compile-flags: -Zmin-function-alignment=8
+
+// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]`
+// nameres ambiguity
+#![feature(rustc_attrs)]
 #![feature(fn_align)]
 
 // When a function uses `align(N)`, the function address should be a multiple of `N`.
 
-#[align(256)]
+#[rustc_align(256)]
 fn foo() {}
 
-#[align(16)]
+#[rustc_align(16)]
 fn bar() {}
 
-#[align(4)]
+#[rustc_align(4)]
 fn baz() {}
 
 fn main() {
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index 726d4c01cc3..e2cd08733af 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -349,12 +349,15 @@ fn simd_mask() {
     // Non-power-of-2 multi-byte mask.
     #[repr(simd, packed)]
     #[allow(non_camel_case_types)]
-    #[derive(Copy, Clone, Debug, PartialEq)]
+    #[derive(Copy, Clone)]
     struct i32x10([i32; 10]);
     impl i32x10 {
         fn splat(x: i32) -> Self {
             Self([x; 10])
         }
+        fn into_array(self) -> [i32; 10] {
+            unsafe { std::mem::transmute(self) }
+        }
     }
     unsafe {
         let mask = i32x10([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]);
@@ -377,19 +380,22 @@ fn simd_mask() {
             i32x10::splat(!0), // yes
             i32x10::splat(0),  // no
         );
-        assert_eq!(selected1, mask);
-        assert_eq!(selected2, mask);
+        assert_eq!(selected1.into_array(), mask.into_array());
+        assert_eq!(selected2.into_array(), mask.into_array());
     }
 
     // Test for a mask where the next multiple of 8 is not a power of two.
     #[repr(simd, packed)]
     #[allow(non_camel_case_types)]
-    #[derive(Copy, Clone, Debug, PartialEq)]
+    #[derive(Copy, Clone)]
     struct i32x20([i32; 20]);
     impl i32x20 {
         fn splat(x: i32) -> Self {
             Self([x; 20])
         }
+        fn into_array(self) -> [i32; 20] {
+            unsafe { std::mem::transmute(self) }
+        }
     }
     unsafe {
         let mask = i32x20([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0, 0, 0, 0, !0, !0, !0, !0, !0, !0, !0]);
@@ -419,8 +425,8 @@ fn simd_mask() {
             i32x20::splat(!0), // yes
             i32x20::splat(0),  // no
         );
-        assert_eq!(selected1, mask);
-        assert_eq!(selected2, mask);
+        assert_eq!(selected1.into_array(), mask.into_array());
+        assert_eq!(selected2.into_array(), mask.into_array());
     }
 }
 
@@ -708,12 +714,12 @@ fn simd_ops_non_pow2() {
     let x = SimdPacked([1u32; 3]);
     let y = SimdPacked([2u32; 3]);
     let z = unsafe { intrinsics::simd_add(x, y) };
-    assert_eq!({ z.0 }, [3u32; 3]);
+    assert_eq!(unsafe { *(&raw const z).cast::<[u32; 3]>() }, [3u32; 3]);
 
     let x = SimdPadded([1u32; 3]);
     let y = SimdPadded([2u32; 3]);
     let z = unsafe { intrinsics::simd_add(x, y) };
-    assert_eq!(z.0, [3u32; 3]);
+    assert_eq!(unsafe { *(&raw const z).cast::<[u32; 3]>() }, [3u32; 3]);
 }
 
 fn main() {
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index d41dc80e6b2..e6e4c711c0c 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -48,7 +48,7 @@ impl Environment {
     }
 
     pub fn build_artifacts(&self) -> Utf8PathBuf {
-        self.build_root().join("build").join(&self.host_tuple)
+        self.build_root().join(&self.host_tuple)
     }
 
     pub fn artifact_dir(&self) -> Utf8PathBuf {
diff --git a/src/tools/opt-dist/src/exec.rs b/src/tools/opt-dist/src/exec.rs
index 56eff2ca2a7..a8d4c93d160 100644
--- a/src/tools/opt-dist/src/exec.rs
+++ b/src/tools/opt-dist/src/exec.rs
@@ -99,7 +99,7 @@ pub struct Bootstrap {
 
 impl Bootstrap {
     pub fn build(env: &Environment) -> Self {
-        let metrics_path = env.build_root().join("build").join("metrics.json");
+        let metrics_path = env.build_root().join("metrics.json");
         let cmd = cmd(&[
             env.python_binary(),
             env.checkout_path().join("x.py").as_str(),
@@ -119,7 +119,7 @@ impl Bootstrap {
     }
 
     pub fn dist(env: &Environment, dist_args: &[String]) -> Self {
-        let metrics_path = env.build_root().join("build").join("metrics.json");
+        let metrics_path = env.build_root().join("metrics.json");
         let args = dist_args.iter().map(|arg| arg.as_str()).collect::<Vec<_>>();
         let cmd = cmd(&args).env("RUST_BACKTRACE", "full");
         let mut cmd = add_shared_x_flags(env, cmd);
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 7857f196626..42170ff39d7 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -62,7 +62,7 @@ enum EnvironmentCmd {
         python: String,
 
         /// Directory where artifacts (like PGO profiles or rustc-perf) of this workflow
-        /// will be stored.
+        /// will be stored. Relative to `checkout_dir`
         #[arg(long, default_value = "opt-artifacts")]
         artifact_dir: Utf8PathBuf,
 
@@ -102,6 +102,11 @@ enum EnvironmentCmd {
         /// Will be LLVM built during the run?
         #[arg(long, default_value_t = true, action(clap::ArgAction::Set))]
         build_llvm: bool,
+
+        /// Set build artifacts dir. Relative to `checkout_dir`, should point to the directory set
+        /// in bootstrap.toml via `build.build-dir` option
+        #[arg(long, default_value = "build")]
+        build_dir: Utf8PathBuf,
     },
     /// Perform an optimized build on Linux CI, from inside Docker.
     LinuxCi {
@@ -138,14 +143,15 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
             shared,
             run_tests,
             build_llvm,
+            build_dir,
         } => {
             let env = EnvironmentBuilder::default()
                 .host_tuple(target_triple)
                 .python_binary(python)
                 .checkout_dir(checkout_dir.clone())
                 .host_llvm_dir(llvm_dir)
-                .artifact_dir(artifact_dir)
-                .build_dir(checkout_dir)
+                .artifact_dir(checkout_dir.join(artifact_dir))
+                .build_dir(checkout_dir.join(build_dir))
                 .prebuilt_rustc_perf(rustc_perf_checkout_dir)
                 .shared_llvm(llvm_shared)
                 .use_bolt(use_bolt)
@@ -171,7 +177,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .checkout_dir(checkout_dir.clone())
                 .host_llvm_dir(Utf8PathBuf::from("/rustroot"))
                 .artifact_dir(Utf8PathBuf::from("/tmp/tmp-multistage/opt-artifacts"))
-                .build_dir(checkout_dir.join("obj"))
+                .build_dir(checkout_dir.join("obj").join("build"))
                 .shared_llvm(true)
                 // FIXME: Enable bolt for aarch64 once it's fixed upstream. Broken as of December 2024.
                 .use_bolt(!is_aarch64)
@@ -194,7 +200,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .checkout_dir(checkout_dir.clone())
                 .host_llvm_dir(checkout_dir.join("citools").join("clang-rust"))
                 .artifact_dir(checkout_dir.join("opt-artifacts"))
-                .build_dir(checkout_dir)
+                .build_dir(checkout_dir.join("build"))
                 .shared_llvm(false)
                 .use_bolt(false)
                 .skipped_tests(vec![])
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 2d2aab86eda..c3c45d262dd 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -13,7 +13,7 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
     // and then use that extracted rustc as a stage0 compiler.
     // Then we run a subset of tests using that compiler, to have a basic smoke test which checks
     // whether the optimization pipeline hasn't broken something.
-    let build_dir = env.build_root().join("build");
+    let build_dir = env.build_root();
     let dist_dir = build_dir.join("dist");
     let unpacked_dist_dir = build_dir.join("unpacked-dist");
     std::fs::create_dir_all(&unpacked_dist_dir)?;
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 1ea549ca7ea..08ba1388dc1 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -52,13 +52,20 @@ impl Rustc {
     // `rustc` invocation constructor methods
 
     /// Construct a new `rustc` invocation. This will automatically set the library
-    /// search path as `-L cwd()` and also the compilation target.
+    /// search path as `-L cwd()`, configure the compilation target and enable
+    /// dynamic linkage by default on musl hosts.
     /// Use [`bare_rustc`] to avoid this.
     #[track_caller]
     pub fn new() -> Self {
         let mut cmd = setup_common();
         cmd.arg("-L").arg(cwd());
 
+        // FIXME: On musl hosts, we currently default to static linkage, while
+        // for running run-make tests, we rely on dynamic linkage by default
+        if std::env::var("IS_MUSL_HOST").is_ok_and(|i| i == "1") {
+            cmd.arg("-Ctarget-feature=-crt-static");
+        }
+
         // Automatically default to cross-compilation
         Self { cmd, target: Some(target()) }
     }
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index e55cd80943d..c471234bbe3 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1268,7 +1268,7 @@ dependencies = [
  "expect-test",
  "intern",
  "parser",
- "ra-ap-rustc_lexer",
+ "ra-ap-rustc_lexer 0.122.0",
  "rustc-hash 2.1.1",
  "smallvec",
  "span",
@@ -1504,7 +1504,7 @@ dependencies = [
  "drop_bomb",
  "edition",
  "expect-test",
- "ra-ap-rustc_lexer",
+ "ra-ap-rustc_lexer 0.122.0",
  "rustc-literal-escaper",
  "stdx",
  "tracing",
@@ -1614,7 +1614,7 @@ dependencies = [
  "object",
  "paths",
  "proc-macro-test",
- "ra-ap-rustc_lexer",
+ "ra-ap-rustc_lexer 0.122.0",
  "span",
  "syntax-bridge",
  "tt",
@@ -1756,9 +1756,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.121.0"
+version = "0.122.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ee51482d1c9d3e538acda8cce723db8eea1a81540544bf362bf4c3d841b2329"
+checksum = "fb01e1fec578003c85481c1cad4ff8cd8195b07c2dc85ae3f716108507ae15d5"
 dependencies = [
  "bitflags 2.9.1",
  "ra-ap-rustc_hashes",
@@ -1768,18 +1768,18 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_hashes"
-version = "0.121.0"
+version = "0.122.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19c8f1e0c28e24e1b4c55dc08058c6c9829df2204497d4034259f491d348c204"
+checksum = "e0ec056e72a472ffef8761ce96ece6c626eb07368c09d0105b6df30d27d07673"
 dependencies = [
  "rustc-stable-hash",
 ]
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.121.0"
+version = "0.122.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f33f429cec6b92fa2c7243883279fb29dd233fdc3e94099aff32aa91aa87f50"
+checksum = "0fcdd1001db0295e59052e9f53aeda588bbe81e362534f4687d41bd44777b5a7"
 dependencies = [
  "ra-ap-rustc_index_macros",
  "smallvec",
@@ -1787,9 +1787,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.121.0"
+version = "0.122.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9b55910dbe1fe7ef34bdc1d1bcb41e99b377eb680ea58a1218d95d6b4152257"
+checksum = "728d64dd98e25530b32e3f7c7c1e844e52722b269360daa1cdeba9dff9727a26"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1808,20 +1808,31 @@ dependencies = [
 ]
 
 [[package]]
+name = "ra-ap-rustc_lexer"
+version = "0.122.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "415f0821f512608d825b3215489a6a6a2c18ed9f0045953d514e7ec23d4b90ab"
+dependencies = [
+ "memchr",
+ "unicode-properties",
+ "unicode-xid",
+]
+
+[[package]]
 name = "ra-ap-rustc_parse_format"
 version = "0.121.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "81057891bc2063ad9e353f29462fbc47a0f5072560af34428ae9313aaa5e9d97"
 dependencies = [
- "ra-ap-rustc_lexer",
+ "ra-ap-rustc_lexer 0.121.0",
  "rustc-literal-escaper",
 ]
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.121.0"
+version = "0.122.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe21a3542980d56d2435e96c2720773cac1c63fd4db666417e414729da192eb3"
+checksum = "4657fcfdfe06e2a02ec8180d4e7c95aecf4811ba50367e363d1a2300b7623284"
 dependencies = [
  "ra-ap-rustc_index",
  "rustc-hash 2.1.1",
@@ -2581,7 +2592,7 @@ version = "0.0.0"
 dependencies = [
  "arrayvec",
  "intern",
- "ra-ap-rustc_lexer",
+ "ra-ap-rustc_lexer 0.122.0",
  "stdx",
  "text-size",
 ]
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 41fa06a76a7..700c116ec18 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -89,11 +89,11 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 edition = { path = "./crates/edition", version = "0.0.0" }
 
-ra-ap-rustc_lexer = { version = "0.121", default-features = false }
+ra-ap-rustc_lexer = { version = "0.122", default-features = false }
 ra-ap-rustc_parse_format = { version = "0.121", default-features = false }
-ra-ap-rustc_index = { version = "0.121", default-features = false }
-ra-ap-rustc_abi = { version = "0.121", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.121", default-features = false }
+ra-ap-rustc_index = { version = "0.122", default-features = false }
+ra-ap-rustc_abi = { version = "0.122", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.122", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 
diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
index 0ec082dfa7f..aed00aa9fc4 100644
--- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
+++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
@@ -68,6 +68,11 @@ impl CfgExpr {
         next_cfg_expr(&mut tt.iter()).unwrap_or(CfgExpr::Invalid)
     }
 
+    #[cfg(feature = "tt")]
+    pub fn parse_from_iter<S: Copy>(tt: &mut tt::iter::TtIter<'_, S>) -> CfgExpr {
+        next_cfg_expr(tt).unwrap_or(CfgExpr::Invalid)
+    }
+
     /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
     pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option<bool> {
         match self {
@@ -96,7 +101,14 @@ fn next_cfg_expr<S: Copy>(it: &mut tt::iter::TtIter<'_, S>) -> Option<CfgExpr> {
     };
 
     let ret = match it.peek() {
-        Some(TtElement::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => {
+        Some(TtElement::Leaf(tt::Leaf::Punct(punct)))
+            // Don't consume on e.g. `=>`.
+            if punct.char == '='
+                && (punct.spacing == tt::Spacing::Alone
+                    || it.remaining().flat_tokens().get(1).is_none_or(|peek2| {
+                        !matches!(peek2, tt::TokenTree::Leaf(tt::Leaf::Punct(_)))
+                    })) =>
+        {
             match it.remaining().flat_tokens().get(1) {
                 Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
                     it.next();
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 1c3af47d522..eeaf865338b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -550,3 +550,51 @@ fn main() { "\"hello\""; }
 "##]],
     );
 }
+
+#[test]
+fn cfg_select() {
+    check(
+        r#"
+#[rustc_builtin_macro]
+pub macro cfg_select($($tt:tt)*) {}
+
+cfg_select! {
+    false => { fn false_1() {} }
+    any(false, true) => { fn true_1() {} }
+}
+
+cfg_select! {
+    false => { fn false_2() {} }
+    _ => { fn true_2() {} }
+}
+
+cfg_select! {
+    false => { fn false_3() {} }
+}
+
+cfg_select! {
+    false
+}
+
+cfg_select! {
+    false =>
+}
+
+    "#,
+        expect![[r#"
+#[rustc_builtin_macro]
+pub macro cfg_select($($tt:tt)*) {}
+
+fn true_1() {}
+
+fn true_2() {}
+
+/* error: none of the predicates in this `cfg_select` evaluated to true */
+
+/* error: expected `=>` after cfg expression */
+
+/* error: expected a token tree after `=>` */
+
+    "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
index 60fbc660652..4a9af01091f 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs
@@ -127,6 +127,7 @@ register_builtin! {
     (asm, Asm) => asm_expand,
     (global_asm, GlobalAsm) => global_asm_expand,
     (naked_asm, NakedAsm) => naked_asm_expand,
+    (cfg_select, CfgSelect) => cfg_select_expand,
     (cfg, Cfg) => cfg_expand,
     (core_panic, CorePanic) => panic_expand,
     (std_panic, StdPanic) => panic_expand,
@@ -355,6 +356,71 @@ fn naked_asm_expand(
     ExpandResult::ok(expanded)
 }
 
+fn cfg_select_expand(
+    db: &dyn ExpandDatabase,
+    id: MacroCallId,
+    tt: &tt::TopSubtree,
+    span: Span,
+) -> ExpandResult<tt::TopSubtree> {
+    let loc = db.lookup_intern_macro_call(id);
+    let cfg_options = loc.krate.cfg_options(db);
+
+    let mut iter = tt.iter();
+    let mut expand_to = None;
+    while let Some(next) = iter.peek() {
+        let active = if let tt::TtElement::Leaf(tt::Leaf::Ident(ident)) = next
+            && ident.sym == sym::underscore
+        {
+            iter.next();
+            true
+        } else {
+            cfg_options.check(&CfgExpr::parse_from_iter(&mut iter)) != Some(false)
+        };
+        match iter.expect_glued_punct() {
+            Ok(it) if it.len() == 2 && it[0].char == '=' && it[1].char == '>' => {}
+            _ => {
+                let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span);
+                return ExpandResult::new(
+                    tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
+                    ExpandError::other(err_span, "expected `=>` after cfg expression"),
+                );
+            }
+        }
+        let expand_to_if_active = match iter.next() {
+            Some(tt::TtElement::Subtree(_, tt)) => tt.remaining(),
+            _ => {
+                let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span);
+                return ExpandResult::new(
+                    tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
+                    ExpandError::other(err_span, "expected a token tree after `=>`"),
+                );
+            }
+        };
+
+        if expand_to.is_none() && active {
+            expand_to = Some(expand_to_if_active);
+        }
+    }
+    match expand_to {
+        Some(expand_to) => {
+            let mut builder = tt::TopSubtreeBuilder::new(tt::Delimiter {
+                kind: tt::DelimiterKind::Invisible,
+                open: span,
+                close: span,
+            });
+            builder.extend_with_tt(expand_to);
+            ExpandResult::ok(builder.build())
+        }
+        None => ExpandResult::new(
+            tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
+            ExpandError::other(
+                span,
+                "none of the predicates in this `cfg_select` evaluated to true",
+            ),
+        ),
+    }
+}
+
 fn cfg_expand(
     db: &dyn ExpandDatabase,
     id: MacroCallId,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
index c7b97dcd231..55a09c5d775 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_deref.rs
@@ -10,7 +10,7 @@ use syntax::{
 use crate::{
     AssistId,
     assist_context::{AssistContext, Assists, SourceChangeBuilder},
-    utils::generate_trait_impl_text,
+    utils::generate_trait_impl_text_intransitive,
 };
 
 // Assist: generate_deref
@@ -150,7 +150,7 @@ fn generate_edit(
         ),
     };
     let strukt_adt = ast::Adt::Struct(strukt);
-    let deref_impl = generate_trait_impl_text(
+    let deref_impl = generate_trait_impl_text_intransitive(
         &strukt_adt,
         &trait_path.display(db, edition).to_string(),
         &impl_code,
@@ -228,6 +228,28 @@ impl core::ops::Deref for B {
     }
 
     #[test]
+    fn test_generate_record_deref_with_generic() {
+        check_assist(
+            generate_deref,
+            r#"
+//- minicore: deref
+struct A<T>($0T);
+"#,
+            r#"
+struct A<T>(T);
+
+impl<T> core::ops::Deref for A<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
     fn test_generate_record_deref_short_path() {
         check_assist(
             generate_deref,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
index 4ddab2cfad0..dc26ec79a74 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs
@@ -134,6 +134,9 @@ fn get_trait_mut(apply_trait: &hir::Trait, famous: FamousDefs<'_, '_>) -> Option
     if trait_ == famous.core_borrow_Borrow().as_ref() {
         return Some("BorrowMut");
     }
+    if trait_ == famous.core_ops_Deref().as_ref() {
+        return Some("DerefMut");
+    }
     None
 }
 
@@ -142,6 +145,7 @@ fn process_method_name(name: ast::Name) -> Option<(ast::Name, &'static str)> {
         "index" => "index_mut",
         "as_ref" => "as_mut",
         "borrow" => "borrow_mut",
+        "deref" => "deref_mut",
         _ => return None,
     };
     Some((name, new_name))
@@ -260,6 +264,39 @@ impl core::convert::AsRef<i32> for Foo {
 }
 "#,
         );
+
+        check_assist(
+            generate_mut_trait_impl,
+            r#"
+//- minicore: deref
+struct Foo(i32);
+
+impl core::ops::Deref$0 for Foo {
+    type Target = i32;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+"#,
+            r#"
+struct Foo(i32);
+
+$0impl core::ops::DerefMut for Foo {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+impl core::ops::Deref for Foo {
+    type Target = i32;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+"#,
+        );
     }
 
     #[test]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index 2c8cb6e4d91..fbce1d31eae 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -567,6 +567,7 @@ pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String {
 ///
 /// This is useful for traits like `PartialEq`, since `impl<T> PartialEq for U<T>` often requires `T: PartialEq`.
 // FIXME: migrate remaining uses to `generate_trait_impl`
+#[allow(dead_code)]
 pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String {
     generate_impl_text_inner(adt, Some(trait_text), true, code)
 }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index 4efb83ba323..9cf0bcf9190 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -531,7 +531,7 @@ impl<'a> FindUsages<'a> {
         node.token_at_offset(offset)
             .find(|it| {
                 // `name` is stripped of raw ident prefix. See the comment on name retrieval below.
-                it.text().trim_start_matches("r#") == name
+                it.text().trim_start_matches('\'').trim_start_matches("r#") == name
             })
             .into_iter()
             .flat_map(move |token| {
@@ -938,7 +938,12 @@ impl<'a> FindUsages<'a> {
                     })
                 };
                 // We need to search without the `r#`, hence `as_str` access.
-                self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.as_str().to_smolstr())
+                // We strip `'` from lifetimes and labels as otherwise they may not match with raw-escaped ones,
+                // e.g. if we search `'foo` we won't find `'r#foo`.
+                self.def
+                    .name(sema.db)
+                    .or_else(self_kw_refs)
+                    .map(|it| it.as_str().trim_start_matches('\'').to_smolstr())
             }
         };
         let name = match &name {
diff --git a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
index c081796d078..698fd147789 100755
--- a/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs
@@ -48,7 +48,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
     let mut res = vec![];
     let mut visited_comments = FxHashSet::default();
     let mut visited_nodes = FxHashSet::default();
-    let mut merged_fn_bodies = FxHashSet::default();
 
     // regions can be nested, here is a LIFO buffer
     let mut region_starts: Vec<TextSize> = vec![];
@@ -73,7 +72,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
                                 continue;
                             }
 
-                            if let Some(body) = fn_node.body() {
+                            if fn_node.body().is_some() {
                                 res.push(Fold {
                                     range: TextRange::new(
                                         node.text_range().start(),
@@ -81,7 +80,6 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
                                     ),
                                     kind: FoldKind::Function,
                                 });
-                                merged_fn_bodies.insert(body.syntax().text_range());
                                 continue;
                             }
                         }
diff --git a/src/tools/rust-analyzer/crates/ide/src/references.rs b/src/tools/rust-analyzer/crates/ide/src/references.rs
index fe874bc99b4..86b88a17c75 100644
--- a/src/tools/rust-analyzer/crates/ide/src/references.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/references.rs
@@ -3088,4 +3088,42 @@ fn main() {
             "#]],
         );
     }
+
+    #[test]
+    fn raw_labels_and_lifetimes() {
+        check(
+            r#"
+fn foo<'r#fn>(s: &'r#fn str) {
+    let _a: &'r#fn str = s;
+    let _b: &'r#fn str;
+    'r#break$0: {
+        break 'r#break;
+    }
+}
+        "#,
+            expect![[r#"
+                'r#break Label FileId(0) 87..96 87..95
+
+                FileId(0) 113..121
+            "#]],
+        );
+        check(
+            r#"
+fn foo<'r#fn$0>(s: &'r#fn str) {
+    let _a: &'r#fn str = s;
+    let _b: &'r#fn str;
+    'r#break: {
+        break 'r#break;
+    }
+}
+        "#,
+            expect![[r#"
+                'r#fn LifetimeParam FileId(0) 7..12
+
+                FileId(0) 18..23
+                FileId(0) 44..49
+                FileId(0) 72..77
+            "#]],
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index 1ccd20c25e9..4780743c4d9 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -156,6 +156,7 @@ define_symbols! {
     cfg_attr,
     cfg_eval,
     cfg,
+    cfg_select,
     char,
     clone,
     Clone,
diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs
index 3246156f1cb..2e89d762a0e 100644
--- a/src/tools/rust-analyzer/crates/tt/src/iter.rs
+++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs
@@ -217,6 +217,17 @@ pub enum TtElement<'a, S> {
     Subtree(&'a Subtree<S>, TtIter<'a, S>),
 }
 
+impl<S: Copy + fmt::Debug> fmt::Debug for TtElement<'_, S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::Leaf(leaf) => f.debug_tuple("Leaf").field(leaf).finish(),
+            Self::Subtree(subtree, inner) => {
+                f.debug_tuple("Subtree").field(subtree).field(inner).finish()
+            }
+        }
+    }
+}
+
 impl<S: Copy> TtElement<'_, S> {
     #[inline]
     pub fn first_span(&self) -> S {
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 57ff326ce5a..c2b1c151b83 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-a9fb6103b05c6ad6eee6bed4c0bb5a2e8e1024c6
+e05ab47e6c418fb2b9faa2eae9a7e70c65c98eaa