about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTshepang Mbambo <hopsi@tuta.io>2025-08-04 15:20:57 +0200
committerGitHub <noreply@github.com>2025-08-04 15:20:57 +0200
commita13caaae3e87d9084a16f023e91880dd2ef0bc09 (patch)
treead7f71f36fed97f65204d8a1f8c594c8ac1d2df8 /src
parent788845811e076df8edceccd49e174d2b3ec4e71d (diff)
parent682a6e17e4dcc02944b00834f11e7cdd7067ebd1 (diff)
downloadrust-a13caaae3e87d9084a16f023e91880dd2ef0bc09.tar.gz
rust-a13caaae3e87d9084a16f023e91880dd2ef0bc09.zip
Merge pull request #2533 from rust-lang/rustc-pull
Rustc pull update
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs19
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs24
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs30
-rw-r--r--src/bootstrap/src/core/build_steps/install.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs16
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs2
-rw-r--r--src/bootstrap/src/core/builder/mod.rs16
-rw-r--r--src/bootstrap/src/core/builder/tests.rs46
-rw-r--r--src/bootstrap/src/core/config/config.rs12
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs27
-rw-r--r--src/bootstrap/src/core/config/toml/target.rs8
-rw-r--r--src/bootstrap/src/lib.rs40
-rw-r--r--src/bootstrap/src/utils/build_stamp.rs6
-rwxr-xr-xsrc/ci/scripts/install-rust.sh15
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md1
-rw-r--r--src/librustdoc/clean/auto_trait.rs40
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/clean/types.rs60
-rw-r--r--src/librustdoc/doctest.rs3
-rw-r--r--src/librustdoc/formats/cache.rs2
-rw-r--r--src/librustdoc/html/format.rs27
-rw-r--r--src/librustdoc/html/render/mod.rs6
-rw-r--r--src/librustdoc/json/conversions.rs10
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs32
-rw-r--r--src/librustdoc/passes/propagate_stability.rs2
-rw-r--r--src/rustdoc-json-types/lib.rs7
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/float_literal.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs35
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs3
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs3
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.stderr2
-rw-r--r--src/tools/compiletest/src/directives.rs10
-rw-r--r--src/tools/compiletest/src/directives/directive_names.rs1
-rw-r--r--src/tools/compiletest/src/directives/tests.rs18
-rw-r--r--src/tools/compiletest/src/runtest.rs114
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc.rs4
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs4
-rw-r--r--src/tools/miri/src/helpers.rs39
-rw-r--r--src/tools/miri/src/lib.rs5
-rw-r--r--src/tools/miri/src/machine.rs2
-rw-r--r--src/tools/run-make-support/src/artifact_names.rs2
-rw-r--r--src/tools/run-make-support/src/external_deps/llvm.rs30
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs6
-rw-r--r--src/tools/run-make-support/src/lib.rs5
-rw-r--r--src/tools/rustbook/Cargo.lock27
-rw-r--r--src/version2
83 files changed, 506 insertions, 371 deletions
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index b4232409ba8..f6653ed899b 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -13,7 +13,7 @@ use crate::core::builder::{
 };
 use crate::core::config::TargetSelection;
 use crate::utils::build_stamp::{self, BuildStamp};
-use crate::{Compiler, Mode, Subcommand};
+use crate::{CodegenBackendKind, Compiler, Mode, Subcommand};
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
@@ -312,7 +312,7 @@ fn prepare_compiler_for_check(
 pub struct CodegenBackend {
     pub build_compiler: Compiler,
     pub target: TargetSelection,
-    pub backend: &'static str,
+    pub backend: CodegenBackendKind,
 }
 
 impl Step for CodegenBackend {
@@ -327,14 +327,14 @@ impl Step for CodegenBackend {
     fn make_run(run: RunConfig<'_>) {
         // FIXME: only check the backend(s) that were actually selected in run.paths
         let build_compiler = prepare_compiler_for_check(run.builder, run.target, Mode::Codegen);
-        for &backend in &["cranelift", "gcc"] {
+        for backend in [CodegenBackendKind::Cranelift, CodegenBackendKind::Gcc] {
             run.builder.ensure(CodegenBackend { build_compiler, target: run.target, backend });
         }
     }
 
     fn run(self, builder: &Builder<'_>) {
         // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
-        if builder.build.config.vendor && self.backend == "gcc" {
+        if builder.build.config.vendor && self.backend.is_gcc() {
             println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
             return;
         }
@@ -354,19 +354,22 @@ impl Step for CodegenBackend {
 
         cargo
             .arg("--manifest-path")
-            .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
+            .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name())));
         rustc_cargo_env(builder, &mut cargo, target);
 
-        let _guard = builder.msg_check(format!("rustc_codegen_{backend}"), target, None);
+        let _guard = builder.msg_check(backend.crate_name(), target, None);
 
-        let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, backend)
+        let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, &backend)
             .with_prefix("check");
 
         run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
     }
 
     fn metadata(&self) -> Option<StepMetadata> {
-        Some(StepMetadata::check(self.backend, self.target).built_by(self.build_compiler))
+        Some(
+            StepMetadata::check(&self.backend.crate_name(), self.target)
+                .built_by(self.build_compiler),
+        )
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 4abfe1843eb..59541bf12de 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -33,7 +33,10 @@ use crate::utils::exec::command;
 use crate::utils::helpers::{
     exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
 };
-use crate::{CLang, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode, debug, trace};
+use crate::{
+    CLang, CodegenBackendKind, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode,
+    debug, trace,
+};
 
 /// Build a standard library for the given `target` using the given `compiler`.
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -1330,7 +1333,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
     }
 
     if let Some(backend) = builder.config.default_codegen_backend(target) {
-        cargo.env("CFG_DEFAULT_CODEGEN_BACKEND", backend);
+        cargo.env("CFG_DEFAULT_CODEGEN_BACKEND", backend.name());
     }
 
     let libdir_relative = builder.config.libdir_relative().unwrap_or_else(|| Path::new("lib"));
@@ -1543,7 +1546,7 @@ impl Step for RustcLink {
 pub struct CodegenBackend {
     pub target: TargetSelection,
     pub compiler: Compiler,
-    pub backend: String,
+    pub backend: CodegenBackendKind,
 }
 
 fn needs_codegen_config(run: &RunConfig<'_>) -> bool {
@@ -1568,7 +1571,7 @@ fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool {
     if path.contains(CODEGEN_BACKEND_PREFIX) {
         let mut needs_codegen_backend_config = true;
         for backend in run.builder.config.codegen_backends(run.target) {
-            if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend)) {
+            if path.ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + backend.name())) {
                 needs_codegen_backend_config = false;
             }
         }
@@ -1602,7 +1605,7 @@ impl Step for CodegenBackend {
         }
 
         for backend in run.builder.config.codegen_backends(run.target) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 continue; // Already built as part of rustc
             }
 
@@ -1663,20 +1666,21 @@ impl Step for CodegenBackend {
         );
         cargo
             .arg("--manifest-path")
-            .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
+            .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name())));
         rustc_cargo_env(builder, &mut cargo, target);
 
         // Ideally, we'd have a separate step for the individual codegen backends,
         // like we have in tests (test::CodegenGCC) but that would require a lot of restructuring.
         // If the logic gets more complicated, it should probably be done.
-        if backend == "gcc" {
+        if backend.is_gcc() {
             let gcc = builder.ensure(Gcc { target });
             add_cg_gcc_cargo_flags(&mut cargo, &gcc);
         }
 
         let tmp_stamp = BuildStamp::new(&out_dir).with_prefix("tmp");
 
-        let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target);
+        let _guard =
+            builder.msg_build(compiler, format_args!("codegen backend {}", backend.name()), target);
         let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false);
         if builder.config.dry_run() {
             return;
@@ -1731,7 +1735,7 @@ fn copy_codegen_backends_to_sysroot(
     }
 
     for backend in builder.config.codegen_backends(target) {
-        if backend == "llvm" {
+        if backend.is_llvm() {
             continue; // Already built as part of rustc
         }
 
@@ -2161,7 +2165,7 @@ impl Step for Assemble {
         let _codegen_backend_span =
             span!(tracing::Level::DEBUG, "building requested codegen backends").entered();
         for backend in builder.config.codegen_backends(target_compiler.host) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 debug!("llvm codegen backend is already built as part of rustc");
                 continue; // Already built as part of rustc
             }
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index c8a54ad250c..4699813abf4 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -32,7 +32,7 @@ use crate::utils::helpers::{
     exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit,
 };
 use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball};
-use crate::{Compiler, DependencyType, FileType, LLVM_TOOLS, Mode, trace};
+use crate::{CodegenBackendKind, Compiler, DependencyType, FileType, LLVM_TOOLS, Mode, trace};
 
 pub fn pkgname(builder: &Builder<'_>, component: &str) -> String {
     format!("{}-{}", component, builder.rust_package_vers())
@@ -1372,10 +1372,10 @@ impl Step for Miri {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct CodegenBackend {
     pub compiler: Compiler,
-    pub backend: String,
+    pub backend: CodegenBackendKind,
 }
 
 impl Step for CodegenBackend {
@@ -1389,7 +1389,7 @@ impl Step for CodegenBackend {
 
     fn make_run(run: RunConfig<'_>) {
         for backend in run.builder.config.codegen_backends(run.target) {
-            if backend == "llvm" {
+            if backend.is_llvm() {
                 continue; // Already built as part of rustc
             }
 
@@ -1412,12 +1412,11 @@ impl Step for CodegenBackend {
             return None;
         }
 
-        if !builder.config.codegen_backends(self.compiler.host).contains(&self.backend.to_string())
-        {
+        if !builder.config.codegen_backends(self.compiler.host).contains(&self.backend) {
             return None;
         }
 
-        if self.backend == "cranelift" && !target_supports_cranelift_backend(self.compiler.host) {
+        if self.backend.is_cranelift() && !target_supports_cranelift_backend(self.compiler.host) {
             builder.info("target not supported by rustc_codegen_cranelift. skipping");
             return None;
         }
@@ -1425,15 +1424,18 @@ impl Step for CodegenBackend {
         let compiler = self.compiler;
         let backend = self.backend;
 
-        let mut tarball =
-            Tarball::new(builder, &format!("rustc-codegen-{backend}"), &compiler.host.triple);
-        if backend == "cranelift" {
+        let mut tarball = Tarball::new(
+            builder,
+            &format!("rustc-codegen-{}", backend.name()),
+            &compiler.host.triple,
+        );
+        if backend.is_cranelift() {
             tarball.set_overlay(OverlayKind::RustcCodegenCranelift);
         } else {
-            panic!("Unknown backend rustc_codegen_{backend}");
+            panic!("Unknown codegen backend {}", backend.name());
         }
         tarball.is_preview(true);
-        tarball.add_legal_and_readme_to(format!("share/doc/rustc_codegen_{backend}"));
+        tarball.add_legal_and_readme_to(format!("share/doc/{}", backend.crate_name()));
 
         let src = builder.sysroot(compiler);
         let backends_src = builder.sysroot_codegen_backends(compiler);
@@ -1445,7 +1447,7 @@ impl Step for CodegenBackend {
         // Don't use custom libdir here because ^lib/ will be resolved again with installer
         let backends_dst = PathBuf::from("lib").join(backends_rel);
 
-        let backend_name = format!("rustc_codegen_{backend}");
+        let backend_name = backend.crate_name();
         let mut found_backend = false;
         for backend in fs::read_dir(&backends_src).unwrap() {
             let file_name = backend.unwrap().file_name();
@@ -1575,7 +1577,7 @@ impl Step for Extended {
         add_component!("analysis" => Analysis { compiler, target });
         add_component!("rustc-codegen-cranelift" => CodegenBackend {
             compiler: builder.compiler(stage, target),
-            backend: "cranelift".to_string(),
+            backend: CodegenBackendKind::Cranelift,
         });
         add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker {
             build_compiler: compiler,
diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs
index 4156b49a8b3..4513a138e19 100644
--- a/src/bootstrap/src/core/build_steps/install.rs
+++ b/src/bootstrap/src/core/build_steps/install.rs
@@ -12,7 +12,7 @@ use crate::core::config::{Config, TargetSelection};
 use crate::utils::exec::command;
 use crate::utils::helpers::t;
 use crate::utils::tarball::GeneratedTarball;
-use crate::{Compiler, Kind};
+use crate::{CodegenBackendKind, Compiler, Kind};
 
 #[cfg(target_os = "illumos")]
 const SHELL: &str = "bash";
@@ -276,7 +276,7 @@ install!((self, builder, _config),
     RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), only_hosts: true, {
         if let Some(tarball) = builder.ensure(dist::CodegenBackend {
             compiler: self.compiler,
-            backend: "cranelift".to_string(),
+            backend: CodegenBackendKind::Cranelift,
         }) {
             install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball);
         } else {
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 951ca73fcc4..ffc5dfad459 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -33,7 +33,7 @@ use crate::utils::helpers::{
     linker_flags, t, target_supports_cranelift_backend, up_to_date,
 };
 use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
-use crate::{CLang, DocTests, GitRepo, Mode, PathSet, debug, envify};
+use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, debug, envify};
 
 const ADB_TEST_DIR: &str = "/data/local/tmp/work";
 
@@ -749,6 +749,12 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             SourceType::InTree,
             &[],
         );
+
+        // Used for `compiletest` self-tests to have the path to the *staged* compiler. Getting this
+        // right is important, as `compiletest` is intended to only support one target spec JSON
+        // format, namely that of the staged compiler.
+        cargo.env("TEST_RUSTC", builder.rustc(compiler));
+
         cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
         run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder);
     }
@@ -1786,7 +1792,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
 
         if let Some(codegen_backend) = builder.config.default_codegen_backend(compiler.host) {
-            cmd.arg("--codegen-backend").arg(&codegen_backend);
+            // Tells compiletest which codegen backend is used by default by the compiler.
+            // It is used to e.g. ignore tests that don't support that codegen backend.
+            cmd.arg("--codegen-backend").arg(codegen_backend.name());
         }
 
         if builder.build.config.llvm_enzyme {
@@ -3406,7 +3414,7 @@ impl Step for CodegenCranelift {
             return;
         }
 
-        if !builder.config.codegen_backends(run.target).contains(&"cranelift".to_owned()) {
+        if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Cranelift) {
             builder.info("cranelift not in rust.codegen-backends. skipping");
             return;
         }
@@ -3533,7 +3541,7 @@ impl Step for CodegenGCC {
             return;
         }
 
-        if !builder.config.codegen_backends(run.target).contains(&"gcc".to_owned()) {
+        if !builder.config.codegen_backends(run.target).contains(&CodegenBackendKind::Gcc) {
             builder.info("gcc not in rust.codegen-backends. skipping");
             return;
         }
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index badd5f24dba..6b3236ef47e 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -1286,7 +1286,7 @@ impl Builder<'_> {
 
             if let Some(limit) = limit
                 && (build_compiler_stage == 0
-                    || self.config.default_codegen_backend(target).unwrap_or_default() == "llvm")
+                    || self.config.default_codegen_backend(target).unwrap_or_default().is_llvm())
             {
                 rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={limit}"));
             }
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 020622d1c12..96289a63785 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -141,7 +141,7 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
 #[allow(unused)]
 #[derive(Debug, PartialEq, Eq)]
 pub struct StepMetadata {
-    name: &'static str,
+    name: String,
     kind: Kind,
     target: TargetSelection,
     built_by: Option<Compiler>,
@@ -151,28 +151,28 @@ pub struct StepMetadata {
 }
 
 impl StepMetadata {
-    pub fn build(name: &'static str, target: TargetSelection) -> Self {
+    pub fn build(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Build)
     }
 
-    pub fn check(name: &'static str, target: TargetSelection) -> Self {
+    pub fn check(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Check)
     }
 
-    pub fn doc(name: &'static str, target: TargetSelection) -> Self {
+    pub fn doc(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Doc)
     }
 
-    pub fn dist(name: &'static str, target: TargetSelection) -> Self {
+    pub fn dist(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Dist)
     }
 
-    pub fn test(name: &'static str, target: TargetSelection) -> Self {
+    pub fn test(name: &str, target: TargetSelection) -> Self {
         Self::new(name, target, Kind::Test)
     }
 
-    fn new(name: &'static str, target: TargetSelection, kind: Kind) -> Self {
-        Self { name, kind, target, built_by: None, stage: None, metadata: None }
+    fn new(name: &str, target: TargetSelection, kind: Kind) -> Self {
+        Self { name: name.to_string(), kind, target, built_by: None, stage: None, metadata: None }
     }
 
     pub fn built_by(mut self, compiler: Compiler) -> Self {
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 6ea5d4e6553..f012645b7ef 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -999,7 +999,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         ");
     }
 
@@ -1048,7 +1048,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1090,7 +1090,7 @@ mod snapshot {
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
         [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1126,8 +1126,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
@@ -1163,7 +1163,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1200,8 +1200,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> LintDocs 1 <host>
         [build] rustc 1 <host> -> std 1 <target1>
@@ -1242,7 +1242,7 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <host>
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 0 <host> -> RustInstaller 1 <host>
         [dist] docs <target1>
@@ -1274,7 +1274,7 @@ mod snapshot {
         [build] rustc 1 <host> -> rustc 2 <host>
         [build] rustc 1 <host> -> WasmComponentLd 2 <host>
         [build] rustdoc 1 <host>
-        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 2 <target1> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         [build] rustc 2 <host> -> std 2 <host>
         [build] rustc 1 <host> -> std 1 <target1>
         [build] rustc 2 <host> -> std 2 <target1>
@@ -1309,8 +1309,8 @@ mod snapshot {
                 .path("compiler")
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1341,8 +1341,8 @@ mod snapshot {
                 .stage(1)
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1358,8 +1358,8 @@ mod snapshot {
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustc 1 <host> -> std 1 <host>
         [check] rustc 1 <host> -> rustc 2 <host>
-        [check] rustc 1 <host> -> cranelift 2 <host>
-        [check] rustc 1 <host> -> gcc 2 <host>
+        [check] rustc 1 <host> -> rustc_codegen_cranelift 2 <host>
+        [check] rustc 1 <host> -> rustc_codegen_gcc 2 <host>
         ");
     }
 
@@ -1377,8 +1377,8 @@ mod snapshot {
         [build] rustc 1 <host> -> std 1 <target1>
         [check] rustc 1 <host> -> rustc 2 <target1>
         [check] rustc 1 <host> -> Rustdoc 2 <target1>
-        [check] rustc 1 <host> -> cranelift 2 <target1>
-        [check] rustc 1 <host> -> gcc 2 <target1>
+        [check] rustc 1 <host> -> rustc_codegen_cranelift 2 <target1>
+        [check] rustc 1 <host> -> rustc_codegen_gcc 2 <target1>
         [check] rustc 1 <host> -> Clippy 2 <target1>
         [check] rustc 1 <host> -> Miri 2 <target1>
         [check] rustc 1 <host> -> CargoMiri 2 <target1>
@@ -1472,8 +1472,8 @@ mod snapshot {
                 .args(&args)
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1557,8 +1557,8 @@ mod snapshot {
                 .path("rustc_codegen_cranelift")
                 .render_steps(), @r"
         [check] rustc 0 <host> -> rustc 1 <host>
-        [check] rustc 0 <host> -> cranelift 1 <host>
-        [check] rustc 0 <host> -> gcc 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_cranelift 1 <host>
+        [check] rustc 0 <host> -> rustc_codegen_gcc 1 <host>
         ");
     }
 
@@ -1620,7 +1620,7 @@ mod snapshot {
         [build] llvm <host>
         [build] rustc 0 <host> -> rustc 1 <host>
         [build] rustdoc 0 <host>
-        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,std,std_detect,sysroot,test,unwind]
+        [doc] std 1 <host> crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind]
         ");
     }
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 78abdd7f9b8..6055876c475 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -51,7 +51,7 @@ use crate::core::download::{
 use crate::utils::channel;
 use crate::utils::exec::{ExecutionContext, command};
 use crate::utils::helpers::{exe, get_host_target};
-use crate::{GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t};
+use crate::{CodegenBackendKind, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t};
 
 /// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic.
 /// This means they can be modified and changes to these paths should never trigger a compiler build
@@ -208,7 +208,7 @@ pub struct Config {
     pub rustc_default_linker: Option<String>,
     pub rust_optimize_tests: bool,
     pub rust_dist_src: bool,
-    pub rust_codegen_backends: Vec<String>,
+    pub rust_codegen_backends: Vec<CodegenBackendKind>,
     pub rust_verify_llvm_ir: bool,
     pub rust_thin_lto_import_instr_limit: Option<u32>,
     pub rust_randomize_layout: bool,
@@ -350,7 +350,7 @@ impl Config {
             channel: "dev".to_string(),
             codegen_tests: true,
             rust_dist_src: true,
-            rust_codegen_backends: vec!["llvm".to_owned()],
+            rust_codegen_backends: vec![CodegenBackendKind::Llvm],
             deny_warnings: true,
             bindir: "bin".into(),
             dist_include_mingw_linker: true,
@@ -1747,7 +1747,7 @@ impl Config {
             .unwrap_or(self.profiler)
     }
 
-    pub fn codegen_backends(&self, target: TargetSelection) -> &[String] {
+    pub fn codegen_backends(&self, target: TargetSelection) -> &[CodegenBackendKind] {
         self.target_config
             .get(&target)
             .and_then(|cfg| cfg.codegen_backends.as_deref())
@@ -1758,7 +1758,7 @@ impl Config {
         self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc)
     }
 
-    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<String> {
+    pub fn default_codegen_backend(&self, target: TargetSelection) -> Option<CodegenBackendKind> {
         self.codegen_backends(target).first().cloned()
     }
 
@@ -1774,7 +1774,7 @@ impl Config {
     }
 
     pub fn llvm_enabled(&self, target: TargetSelection) -> bool {
-        self.codegen_backends(target).contains(&"llvm".to_owned())
+        self.codegen_backends(target).contains(&CodegenBackendKind::Llvm)
     }
 
     pub fn llvm_libunwind(&self, target: TargetSelection) -> LlvmLibunwind {
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index c136bd4a6f9..03da993a17d 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -11,7 +11,9 @@ use crate::core::config::{
     DebuginfoLevel, Merge, ReplaceOpt, RustcLto, StringOrBool, set, threads_from_config,
 };
 use crate::flags::Warnings;
-use crate::{BTreeSet, Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+use crate::{
+    BTreeSet, CodegenBackendKind, Config, HashSet, PathBuf, TargetSelection, define_config, exit,
+};
 
 define_config! {
     /// TOML representation of how the Rust build is configured.
@@ -389,9 +391,13 @@ pub fn check_incompatible_options_for_ci_rustc(
     Ok(())
 }
 
-pub(crate) const VALID_CODEGEN_BACKENDS: &[&str] = &["llvm", "cranelift", "gcc"];
+pub(crate) const BUILTIN_CODEGEN_BACKENDS: &[&str] = &["llvm", "cranelift", "gcc"];
 
-pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) -> Vec<String> {
+pub(crate) fn parse_codegen_backends(
+    backends: Vec<String>,
+    section: &str,
+) -> Vec<CodegenBackendKind> {
+    let mut found_backends = vec![];
     for backend in &backends {
         if let Some(stripped) = backend.strip_prefix(CODEGEN_BACKEND_PREFIX) {
             panic!(
@@ -400,14 +406,21 @@ pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) ->
                 Please, use '{stripped}' instead."
             )
         }
-        if !VALID_CODEGEN_BACKENDS.contains(&backend.as_str()) {
+        if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.as_str()) {
             println!(
                 "HELP: '{backend}' for '{section}.codegen-backends' might fail. \
-                List of known good values: {VALID_CODEGEN_BACKENDS:?}"
+                List of known codegen backends: {BUILTIN_CODEGEN_BACKENDS:?}"
             );
         }
+        let backend = match backend.as_str() {
+            "llvm" => CodegenBackendKind::Llvm,
+            "cranelift" => CodegenBackendKind::Cranelift,
+            "gcc" => CodegenBackendKind::Gcc,
+            backend => CodegenBackendKind::Custom(backend.to_string()),
+        };
+        found_backends.push(backend);
     }
-    backends
+    found_backends
 }
 
 #[cfg(not(test))]
@@ -609,7 +622,7 @@ impl Config {
                 llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
             set(
                 &mut self.rust_codegen_backends,
-                codegen_backends.map(|backends| validate_codegen_backends(backends, "rust")),
+                codegen_backends.map(|backends| parse_codegen_backends(backends, "rust")),
             );
 
             self.rust_codegen_units = codegen_units.map(threads_from_config);
diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs
index 337276948b3..9dedadff3a1 100644
--- a/src/bootstrap/src/core/config/toml/target.rs
+++ b/src/bootstrap/src/core/config/toml/target.rs
@@ -16,9 +16,9 @@ use std::collections::HashMap;
 
 use serde::{Deserialize, Deserializer};
 
-use crate::core::config::toml::rust::validate_codegen_backends;
+use crate::core::config::toml::rust::parse_codegen_backends;
 use crate::core::config::{LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool};
-use crate::{Config, HashSet, PathBuf, TargetSelection, define_config, exit};
+use crate::{CodegenBackendKind, Config, HashSet, PathBuf, TargetSelection, define_config, exit};
 
 define_config! {
     /// TOML representation of how each build target is configured.
@@ -76,7 +76,7 @@ pub struct Target {
     pub qemu_rootfs: Option<PathBuf>,
     pub runner: Option<String>,
     pub no_std: bool,
-    pub codegen_backends: Option<Vec<String>>,
+    pub codegen_backends: Option<Vec<CodegenBackendKind>>,
     pub optimized_compiler_builtins: Option<bool>,
     pub jemalloc: Option<bool>,
 }
@@ -144,7 +144,7 @@ impl Config {
                 target.jemalloc = cfg.jemalloc;
                 if let Some(backends) = cfg.codegen_backends {
                     target.codegen_backends =
-                        Some(validate_codegen_backends(backends, &format!("target.{triple}")))
+                        Some(parse_codegen_backends(backends, &format!("target.{triple}")))
                 }
 
                 target.split_debuginfo = cfg.split_debuginfo.as_ref().map(|v| {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 51a84ad5272..011b52df97b 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -123,6 +123,46 @@ impl PartialEq for Compiler {
     }
 }
 
+/// Represents a codegen backend.
+#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
+pub enum CodegenBackendKind {
+    #[default]
+    Llvm,
+    Cranelift,
+    Gcc,
+    Custom(String),
+}
+
+impl CodegenBackendKind {
+    /// Name of the codegen backend, as identified in the `compiler` directory
+    /// (`rustc_codegen_<name>`).
+    pub fn name(&self) -> &str {
+        match self {
+            CodegenBackendKind::Llvm => "llvm",
+            CodegenBackendKind::Cranelift => "cranelift",
+            CodegenBackendKind::Gcc => "gcc",
+            CodegenBackendKind::Custom(name) => name,
+        }
+    }
+
+    /// Name of the codegen backend's crate, e.g. `rustc_codegen_cranelift`.
+    pub fn crate_name(&self) -> String {
+        format!("rustc_codegen_{}", self.name())
+    }
+
+    pub fn is_llvm(&self) -> bool {
+        matches!(self, Self::Llvm)
+    }
+
+    pub fn is_cranelift(&self) -> bool {
+        matches!(self, Self::Cranelift)
+    }
+
+    pub fn is_gcc(&self) -> bool {
+        matches!(self, Self::Gcc)
+    }
+}
+
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
 pub enum DocTests {
     /// Run normal tests and doc tests (default).
diff --git a/src/bootstrap/src/utils/build_stamp.rs b/src/bootstrap/src/utils/build_stamp.rs
index f43d860893f..bd4eb790ae5 100644
--- a/src/bootstrap/src/utils/build_stamp.rs
+++ b/src/bootstrap/src/utils/build_stamp.rs
@@ -10,7 +10,7 @@ use sha2::digest::Digest;
 use crate::core::builder::Builder;
 use crate::core::config::TargetSelection;
 use crate::utils::helpers::{hex_encode, mtime};
-use crate::{Compiler, Mode, helpers, t};
+use crate::{CodegenBackendKind, Compiler, Mode, helpers, t};
 
 #[cfg(test)]
 mod tests;
@@ -129,10 +129,10 @@ pub fn codegen_backend_stamp(
     builder: &Builder<'_>,
     compiler: Compiler,
     target: TargetSelection,
-    backend: &str,
+    backend: &CodegenBackendKind,
 ) -> BuildStamp {
     BuildStamp::new(&builder.cargo_out(compiler, Mode::Codegen, target))
-        .with_prefix(&format!("librustc_codegen_{backend}"))
+        .with_prefix(&format!("lib{}", backend.crate_name()))
 }
 
 /// Cargo's output path for the standard library in a given stage, compiled
diff --git a/src/ci/scripts/install-rust.sh b/src/ci/scripts/install-rust.sh
deleted file mode 100755
index e4aee98c9fb..00000000000
--- a/src/ci/scripts/install-rust.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-# The Arm64 Windows Runner does not have Rust already installed
-# https://github.com/actions/partner-runner-images/issues/77
-
-set -euo pipefail
-IFS=$'\n\t'
-
-source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
-
-if [[ "${CI_JOB_NAME}" = *aarch64* ]] && isWindows; then
-    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
-    sh -s -- -y -q --default-host aarch64-pc-windows-msvc
-    ciCommandAddPath "${USERPROFILE}/.cargo/bin"
-fi
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index 1ced6098acf..e9f1626f1fd 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-32e7a4b92b109c24e9822c862a7c74436b50e564
+383b9c447b61641e1f1a3850253944a897a60827
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 1a72699f8e5..f4ba9a044e6 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -297,6 +297,7 @@ See [Pretty-printer](compiletest.md#pretty-printer-tests).
 - [`should-ice`](compiletest.md#incremental-tests) — incremental cfail should
       ICE
 - [`reference`] — an annotation linking to a rule in the reference
+- `disable-gdb-pretty-printers` — disable gdb pretty printers for debuginfo tests
 
 [`reference`]: https://github.com/rust-lang/reference/blob/master/docs/authoring.md#test-rule-annotations
 
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index a91ea55bcae..e6ac0270f78 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -1,6 +1,6 @@
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry};
 use rustc_hir as hir;
-use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
+use rustc_infer::infer::region_constraints::{ConstraintKind, RegionConstraintData};
 use rustc_middle::bug;
 use rustc_middle::ty::{self, Region, Ty, fold_regions};
 use rustc_span::def_id::DefId;
@@ -233,31 +233,35 @@ fn clean_region_outlives_constraints<'tcx>(
     // Each `RegionTarget` (a `RegionVid` or a `Region`) maps to its smaller and larger regions.
     // Note that "larger" regions correspond to sub regions in the surface language.
     // E.g., in `'a: 'b`, `'a` is the larger region.
-    for (constraint, _) in &regions.constraints {
-        match *constraint {
-            Constraint::VarSubVar(vid1, vid2) => {
-                let deps1 = map.entry(RegionTarget::RegionVid(vid1)).or_default();
-                deps1.larger.insert(RegionTarget::RegionVid(vid2));
+    for (c, _) in &regions.constraints {
+        match c.kind {
+            ConstraintKind::VarSubVar => {
+                let sub_vid = c.sub.as_var();
+                let sup_vid = c.sup.as_var();
+                let deps1 = map.entry(RegionTarget::RegionVid(sub_vid)).or_default();
+                deps1.larger.insert(RegionTarget::RegionVid(sup_vid));
 
-                let deps2 = map.entry(RegionTarget::RegionVid(vid2)).or_default();
-                deps2.smaller.insert(RegionTarget::RegionVid(vid1));
+                let deps2 = map.entry(RegionTarget::RegionVid(sup_vid)).or_default();
+                deps2.smaller.insert(RegionTarget::RegionVid(sub_vid));
             }
-            Constraint::RegSubVar(region, vid) => {
-                let deps = map.entry(RegionTarget::RegionVid(vid)).or_default();
-                deps.smaller.insert(RegionTarget::Region(region));
+            ConstraintKind::RegSubVar => {
+                let sup_vid = c.sup.as_var();
+                let deps = map.entry(RegionTarget::RegionVid(sup_vid)).or_default();
+                deps.smaller.insert(RegionTarget::Region(c.sub));
             }
-            Constraint::VarSubReg(vid, region) => {
-                let deps = map.entry(RegionTarget::RegionVid(vid)).or_default();
-                deps.larger.insert(RegionTarget::Region(region));
+            ConstraintKind::VarSubReg => {
+                let sub_vid = c.sub.as_var();
+                let deps = map.entry(RegionTarget::RegionVid(sub_vid)).or_default();
+                deps.larger.insert(RegionTarget::Region(c.sup));
             }
-            Constraint::RegSubReg(r1, r2) => {
+            ConstraintKind::RegSubReg => {
                 // The constraint is already in the form that we want, so we're done with it
                 // The desired order is [larger, smaller], so flip them.
-                if early_bound_region_name(r1) != early_bound_region_name(r2) {
+                if early_bound_region_name(c.sub) != early_bound_region_name(c.sup) {
                     outlives_predicates
-                        .entry(early_bound_region_name(r2).expect("no region_name found"))
+                        .entry(early_bound_region_name(c.sup).expect("no region_name found"))
                         .or_default()
-                        .push(r1);
+                        .push(c.sub);
                 }
             }
         }
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index b6ce8551060..e204e1788ba 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -486,6 +486,7 @@ impl fmt::Display for Display<'_> {
                     (sym::debug_assertions, None) => "debug-assertions enabled",
                     (sym::target_os, Some(os)) => match os.as_str() {
                         "android" => "Android",
+                        "cygwin" => "Cygwin",
                         "dragonfly" => "DragonFly BSD",
                         "emscripten" => "Emscripten",
                         "freebsd" => "FreeBSD",
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 9603399f235..8c0f897c992 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -217,7 +217,7 @@ pub(crate) fn try_inline_glob(
 }
 
 pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir::Attribute] {
-    cx.tcx.get_attrs_unchecked(did)
+    cx.tcx.get_all_attrs(did)
 }
 
 pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<Symbol> {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 14295ce0a31..743ed2b5045 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -36,13 +36,13 @@ use std::mem;
 
 use rustc_ast::token::{Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
 use rustc_errors::codes::*;
 use rustc_errors::{FatalError, struct_span_code_err};
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId};
-use rustc_hir::{LangItem, PredicateOrigin};
+use rustc_hir::{LangItem, PredicateOrigin, find_attr};
 use rustc_hir_analysis::hir_ty_lowering::FeedConstTy;
 use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty};
 use rustc_middle::metadata::Reexport;
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5ac5da24299..782311e593b 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -6,14 +6,12 @@ use std::{fmt, iter};
 use arrayvec::ArrayVec;
 use itertools::Either;
 use rustc_abi::{ExternAbi, VariantIdx};
-use rustc_attr_data_structures::{
-    AttributeKind, ConstStability, Deprecation, Stability, StableSince, find_attr,
-};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation};
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{BodyId, Mutability};
+use rustc_hir::{BodyId, ConstStability, Mutability, Stability, StableSince, find_attr};
 use rustc_index::IndexVec;
 use rustc_metadata::rendered_const;
 use rustc_middle::span_bug;
@@ -387,13 +385,13 @@ impl Item {
             // versions; the paths that are exposed through it are "deprecated" because they
             // were never supposed to work at all.
             let stab = self.stability(tcx)?;
-            if let rustc_attr_data_structures::StabilityLevel::Stable {
+            if let rustc_hir::StabilityLevel::Stable {
                 allowed_through_unstable_modules: Some(note),
                 ..
             } = stab.level
             {
                 Some(Deprecation {
-                    since: rustc_attr_data_structures::DeprecatedSince::Unspecified,
+                    since: DeprecatedSince::Unspecified,
                     note: Some(note),
                     suggestion: None,
                 })
@@ -404,10 +402,7 @@ impl Item {
     }
 
     pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
-        self.item_id
-            .as_def_id()
-            .map(|did| inner_docs(tcx.get_attrs_unchecked(did)))
-            .unwrap_or(false)
+        self.item_id.as_def_id().map(|did| inner_docs(tcx.get_all_attrs(did))).unwrap_or(false)
     }
 
     pub(crate) fn span(&self, tcx: TyCtxt<'_>) -> Option<Span> {
@@ -452,7 +447,7 @@ impl Item {
         kind: ItemKind,
         cx: &mut DocContext<'_>,
     ) -> Item {
-        let hir_attrs = cx.tcx.get_attrs_unchecked(def_id);
+        let hir_attrs = cx.tcx.get_all_attrs(def_id);
 
         Self::from_def_id_and_attrs_and_parts(
             def_id,
@@ -768,13 +763,13 @@ impl Item {
             .iter()
             .filter_map(|attr| match attr {
                 hir::Attribute::Parsed(AttributeKind::LinkSection { name, .. }) => {
-                    Some(format!("#[link_section = \"{name}\"]"))
+                    Some(format!("#[unsafe(link_section = \"{name}\")]"))
                 }
                 hir::Attribute::Parsed(AttributeKind::NoMangle(..)) => {
-                    Some("#[no_mangle]".to_string())
+                    Some("#[unsafe(no_mangle)]".to_string())
                 }
                 hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) => {
-                    Some(format!("#[export_name = \"{name}\"]"))
+                    Some(format!("#[unsafe(export_name = \"{name}\")]"))
                 }
                 hir::Attribute::Parsed(AttributeKind::NonExhaustive(..)) => {
                     Some("#[non_exhaustive]".to_string())
@@ -1963,43 +1958,6 @@ impl PrimitiveType {
     }
 }
 
-impl From<ast::IntTy> for PrimitiveType {
-    fn from(int_ty: ast::IntTy) -> PrimitiveType {
-        match int_ty {
-            ast::IntTy::Isize => PrimitiveType::Isize,
-            ast::IntTy::I8 => PrimitiveType::I8,
-            ast::IntTy::I16 => PrimitiveType::I16,
-            ast::IntTy::I32 => PrimitiveType::I32,
-            ast::IntTy::I64 => PrimitiveType::I64,
-            ast::IntTy::I128 => PrimitiveType::I128,
-        }
-    }
-}
-
-impl From<ast::UintTy> for PrimitiveType {
-    fn from(uint_ty: ast::UintTy) -> PrimitiveType {
-        match uint_ty {
-            ast::UintTy::Usize => PrimitiveType::Usize,
-            ast::UintTy::U8 => PrimitiveType::U8,
-            ast::UintTy::U16 => PrimitiveType::U16,
-            ast::UintTy::U32 => PrimitiveType::U32,
-            ast::UintTy::U64 => PrimitiveType::U64,
-            ast::UintTy::U128 => PrimitiveType::U128,
-        }
-    }
-}
-
-impl From<ast::FloatTy> for PrimitiveType {
-    fn from(float_ty: ast::FloatTy) -> PrimitiveType {
-        match float_ty {
-            ast::FloatTy::F16 => PrimitiveType::F16,
-            ast::FloatTy::F32 => PrimitiveType::F32,
-            ast::FloatTy::F64 => PrimitiveType::F64,
-            ast::FloatTy::F128 => PrimitiveType::F128,
-        }
-    }
-}
-
 impl From<ty::IntTy> for PrimitiveType {
     fn from(int_ty: ty::IntTy) -> PrimitiveType {
         match int_ty {
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 0bef091468f..35ace656638 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -409,7 +409,8 @@ pub(crate) fn run_tests(
         // We ensure temp dir destructor is called.
         std::mem::drop(temp_dir);
         times.display_times();
-        // libtest::ERROR_EXIT_CODE is not public but it's the same value.
+        // FIXME(GuillaumeGomez): Uncomment the next line once #144297 has been merged.
+        // std::process::exit(test::ERROR_EXIT_CODE);
         std::process::exit(101);
     }
 }
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index e28cc3a542e..80399cf3842 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -1,8 +1,8 @@
 use std::mem;
 
 use rustc_ast::join_path_syms;
-use rustc_attr_data_structures::StabilityLevel;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_hir::StabilityLevel;
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
 use rustc_metadata::creader::CStore;
 use rustc_middle::ty::{self, TyCtxt};
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index be8a2d511e9..493fdc6fb1b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -15,11 +15,11 @@ use std::slice;
 use itertools::{Either, Itertools};
 use rustc_abi::ExternAbi;
 use rustc_ast::join_path_syms;
-use rustc_attr_data_structures::{ConstStability, StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
+use rustc_hir::{ConstStability, StabilityLevel, StableSince};
 use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::{self, TyCtxt, TypingMode};
 use rustc_span::symbol::kw;
@@ -368,6 +368,8 @@ pub(crate) enum HrefError {
     Private,
     // Not in external cache, href link should be in same page
     NotInExternalCache,
+    /// Refers to an unnamable item, such as one defined within a function or const block.
+    UnnamableItem,
 }
 
 /// This function is to get the external macro path because they are not in the cache used in
@@ -479,6 +481,26 @@ fn generate_item_def_id_path(
     Ok((url_parts, shortty, fqp))
 }
 
+/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
+fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool {
+    let mut cur_did = did;
+    while let Some(parent) = tcx.opt_parent(cur_did) {
+        match tcx.def_kind(parent) {
+            // items defined in these can be linked to, as long as they are visible
+            DefKind::Mod | DefKind::ForeignMod => cur_did = parent,
+            // items in impls can be linked to,
+            // as long as we can link to the item the impl is on.
+            // since associated traits are not a thing,
+            // it should not be possible to refer to an impl item if
+            // the base type is not namable.
+            DefKind::Impl { .. } => return false,
+            // everything else does not have docs generated for it
+            _ => return true,
+        }
+    }
+    return false;
+}
+
 fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
     if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
 }
@@ -552,6 +574,9 @@ pub(crate) fn href_with_root_path(
         }
         _ => original_did,
     };
+    if is_unnamable(cx.tcx(), did) {
+        return Err(HrefError::UnnamableItem);
+    }
     let cache = cx.cache();
     let relative_to = &cx.current;
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 872dbbcd19e..a46253237db 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -50,12 +50,10 @@ use std::{fs, str};
 use askama::Template;
 use itertools::Either;
 use rustc_ast::join_path_syms;
-use rustc_attr_data_structures::{
-    ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
-};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_hir::Mutability;
+use rustc_hir::attrs::{DeprecatedSince, Deprecation};
 use rustc_hir::def_id::{DefId, DefIdSet};
+use rustc_hir::{ConstStability, Mutability, RustcVersion, StabilityLevel, StableSince};
 use rustc_middle::ty::print::PrintTraitRefExt;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::{Symbol, sym};
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 08bc0bb1950..f966d926562 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -4,8 +4,8 @@
 
 use rustc_abi::ExternAbi;
 use rustc_ast::ast;
-use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
 use rustc_hir as hir;
+use rustc_hir::attrs::{self, DeprecatedSince};
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{HeaderSafety, Safety};
@@ -908,8 +908,12 @@ fn maybe_from_hir_attr(
         hir::Attribute::Parsed(kind) => kind,
 
         hir::Attribute::Unparsed(_) => {
-            // FIXME: We should handle `#[doc(hidden)]`.
-            return Some(other_attr(tcx, attr));
+            return Some(if attr.has_name(sym::macro_export) {
+                Attribute::MacroExport
+                // FIXME: We should handle `#[doc(hidden)]`.
+            } else {
+                other_attr(tcx, attr)
+            });
         }
     };
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 7431ff8e1ad..28dbd8ba7d3 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -32,7 +32,6 @@ extern crate pulldown_cmark;
 extern crate rustc_abi;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
-extern crate rustc_attr_data_structures;
 extern crate rustc_attr_parsing;
 extern crate rustc_data_structures;
 extern crate rustc_driver;
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5a9aa2a94c8..c9fa3a4837f 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -941,13 +941,21 @@ fn preprocess_link(
     ori_link: &MarkdownLink,
     dox: &str,
 ) -> Option<Result<PreprocessingInfo, PreprocessingError>> {
+    // certain link kinds cannot have their path be urls,
+    // so they should not be ignored, no matter how much they look like urls.
+    // e.g. [https://example.com/] is not a link to example.com.
+    let can_be_url = !matches!(
+        ori_link.kind,
+        LinkType::ShortcutUnknown | LinkType::CollapsedUnknown | LinkType::ReferenceUnknown
+    );
+
     // [] is mostly likely not supposed to be a link
     if ori_link.link.is_empty() {
         return None;
     }
 
     // Bail early for real links.
-    if ori_link.link.contains('/') {
+    if can_be_url && ori_link.link.contains('/') {
         return None;
     }
 
@@ -972,7 +980,7 @@ fn preprocess_link(
         Ok(None) => (None, link, link),
         Err((err_msg, relative_range)) => {
             // Only report error if we would not have ignored this link. See issue #83859.
-            if !should_ignore_link_with_disambiguators(link) {
+            if !(can_be_url && should_ignore_link_with_disambiguators(link)) {
                 let disambiguator_range = match range_between_backticks(&ori_link.range, dox) {
                     MarkdownLinkRange::Destination(no_backticks_range) => {
                         MarkdownLinkRange::Destination(
@@ -989,7 +997,25 @@ fn preprocess_link(
         }
     };
 
-    if should_ignore_link(path_str) {
+    // If there's no backticks, be lenient and revert to the old behavior.
+    // This is to prevent churn by linting on stuff that isn't meant to be a link.
+    // only shortcut links have simple enough syntax that they
+    // are likely to be written accidentally, collapsed and reference links
+    // need 4 metachars, and reference links will not usually use
+    // backticks in the reference name.
+    // therefore, only shortcut syntax gets the lenient behavior.
+    //
+    // here's a truth table for how link kinds that cannot be urls are handled:
+    //
+    // |-------------------------------------------------------|
+    // |              |  is shortcut link  | not shortcut link |
+    // |--------------|--------------------|-------------------|
+    // | has backtick |    never ignore    |    never ignore   |
+    // | no backtick  | ignore if url-like |    never ignore   |
+    // |-------------------------------------------------------|
+    let ignore_urllike =
+        can_be_url || (ori_link.kind == LinkType::ShortcutUnknown && !ori_link.link.contains('`'));
+    if ignore_urllike && should_ignore_link(path_str) {
         return None;
     }
 
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs
index 7b3da8d7c0f..14ec58702e3 100644
--- a/src/librustdoc/passes/propagate_stability.rs
+++ b/src/librustdoc/passes/propagate_stability.rs
@@ -6,8 +6,8 @@
 //! [`core::error`] module is marked as stable since 1.81.0, so we want to show
 //! [`core::error::Error`] as stable since 1.81.0 as well.
 
-use rustc_attr_data_structures::{Stability, StabilityLevel};
 use rustc_hir::def_id::CRATE_DEF_ID;
+use rustc_hir::{Stability, StabilityLevel};
 
 use crate::clean::{Crate, Item, ItemId, ItemKind};
 use crate::core::DocContext;
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 6235b0e8576..40f89009a43 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -37,8 +37,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
 // are deliberately not in a doc comment, because they need not be in public docs.)
 //
-// Latest feature: Structured Attributes
-pub const FORMAT_VERSION: u32 = 54;
+// Latest feature: Add Attribute::MacroUse
+pub const FORMAT_VERSION: u32 = 55;
 
 /// The root of the emitted JSON blob.
 ///
@@ -216,6 +216,9 @@ pub enum Attribute {
     /// `#[must_use]`
     MustUse { reason: Option<String> },
 
+    /// `#[macro_export]`
+    MacroExport,
+
     /// `#[export_name = "name"]`
     ExportName(String),
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 9b296973b425ffb159e12cf3cd56580fd5c8538
+Subproject 840b83a10fb0e039a83f4d70ad032892c287570
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 184fbbf7796..ab47e309752 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
-use rustc_attr_data_structures::RustcVersion;
+use rustc_hir::RustcVersion;
 use rustc_hir::{HirId, Lit};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 7b4cf033674..d6469d32931 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -6,7 +6,7 @@ use clippy_config::types::{
 };
 use clippy_utils::diagnostics::span_lint_and_note;
 use clippy_utils::is_cfg_test;
-use rustc_attr_data_structures::AttributeKind;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::{
     Attribute, FieldDef, HirId, ImplItemId, IsAuto, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind, Variant,
     VariantData,
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
index b8f93ee5e2c..409bb698665 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -1,6 +1,7 @@
 use super::INLINE_ALWAYS;
 use clippy_utils::diagnostics::span_lint;
-use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr};
+use rustc_hir::attrs::{AttributeKind, InlineAttr};
+use rustc_hir::find_attr;
 use rustc_hir::Attribute;
 use rustc_lint::LateContext;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
index 3e8808cec61..4ece3ed44fd 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
@@ -1,4 +1,5 @@
-use rustc_attr_data_structures::{AttributeKind, ReprAttr, find_attr};
+use rustc_hir::attrs::{AttributeKind, ReprAttr};
+use rustc_hir::find_attr;
 use rustc_hir::Attribute;
 use rustc_lint::LateContext;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 61c2fc49bd7..ba1135d745a 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -7,7 +7,7 @@ use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{eq_expr_value, sym};
 use rustc_ast::ast::LitKind;
-use rustc_attr_data_structures::RustcVersion;
+use rustc_hir::RustcVersion;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index 9bf2144e445..f41255e54db 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use rustc_attr_data_structures::{AttributeKind, ReprAttr, find_attr};
+use rustc_hir::attrs::{AttributeKind, ReprAttr};
+use rustc_hir::find_attr;
 use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
index ebfc9972aef..1e7d1f92fa3 100644
--- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::AttrStyle;
 use rustc_ast::token::CommentKind;
-use rustc_attr_data_structures::AttributeKind;
+use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
 use rustc_hir::Attribute;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
index 7f7224ecfc6..32ba696b3ec 100644
--- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -1,4 +1,4 @@
-use rustc_attr_data_structures::AttributeKind;
+use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
 use rustc_hir::{Attribute, Item, ItemKind};
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 9b627678bd3..ba539d05b6b 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -7,7 +7,8 @@ use clippy_utils::{
     get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
 };
 use rustc_abi::ExternAbi;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_errors::Applicability;
 use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind};
 use rustc_infer::infer::TyCtxtInferExt;
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index 8ad09279071..5f40e576443 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::indent_of;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs
index c51267567d0..ccaf38aee4d 100644
--- a/src/tools/clippy/clippy_lints/src/float_literal.rs
+++ b/src/tools/clippy/clippy_lints/src/float_literal.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::numeric_literal;
-use rustc_ast::ast::{self, LitFloatType, LitKind};
+use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -75,10 +75,10 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
             let digits = count_digits(sym_str);
             let max = max_digits(fty);
             let type_suffix = match lit_float_ty {
-                LitFloatType::Suffixed(ast::FloatTy::F16) => Some("f16"),
-                LitFloatType::Suffixed(ast::FloatTy::F32) => Some("f32"),
-                LitFloatType::Suffixed(ast::FloatTy::F64) => Some("f64"),
-                LitFloatType::Suffixed(ast::FloatTy::F128) => Some("f128"),
+                LitFloatType::Suffixed(FloatTy::F16) => Some("f16"),
+                LitFloatType::Suffixed(FloatTy::F32) => Some("f32"),
+                LitFloatType::Suffixed(FloatTy::F64) => Some("f64"),
+                LitFloatType::Suffixed(FloatTy::F128) => Some("f128"),
                 LitFloatType::Unsuffixed => None,
             };
             let (is_whole, is_inf, mut float_str) = match fty {
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index a251f15ba3d..af4202422e4 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -17,7 +17,8 @@ use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
     FormatPlaceholder, FormatTrait,
 };
-use rustc_attr_data_structures::{AttributeKind, RustcVersion, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::{find_attr,RustcVersion};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index b8d0cec5aeb..55ca0d9ecb7 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -14,7 +14,8 @@ use clippy_utils::source::snippet_indent;
 use clippy_utils::ty::is_must_use_ty;
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{return_ty, trait_ref_of_method};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_span::Symbol;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 116d63c3bb1..85ebc830d3b 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::Msrv;
 use clippy_utils::{is_in_const_context, is_in_test};
-use rustc_attr_data_structures::{RustcVersion, StabilityLevel, StableSince};
+use rustc_hir::{RustcVersion, StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::DefKind;
 use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, QPath};
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index ffe6ad14f63..ee59a4cc8cb 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sugg::DiagExt;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_errors::Applicability;
 use rustc_hir::{TraitFn, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 96a6dee5885..914aa6b9b80 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -35,7 +35,6 @@ extern crate rustc_abi;
 extern crate rustc_arena;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
-extern crate rustc_attr_data_structures;
 extern crate rustc_data_structures;
 extern crate rustc_driver;
 extern crate rustc_errors;
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index 3aa449f6411..bf89556fbb6 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -1,7 +1,8 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet;
 use hir::def::{DefKind, Res};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, AmbigArg};
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 2d52a93f34e..6b0f7446849 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -4,7 +4,8 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 88b4d9b7d54..027dd7ce053 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -185,7 +185,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
         if let Some(adt) = ty.ty_adt_def()
             && get_attr(
                 self.cx.sess(),
-                self.cx.tcx.get_attrs_unchecked(adt.did()),
+                self.cx.tcx.get_all_attrs(adt.did()),
                 sym::has_significant_drop,
             )
             .count()
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 5a5025973b5..c637fb247ff 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, Attribute};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
index dee8efeb291..791bbbe30a8 100644
--- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use rustc_abi::ExternAbi;
-use rustc_attr_data_structures::AttributeKind;
+use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
 use rustc_hir::{Attribute, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index b8005dfd6f8..303c5dfed89 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -5,7 +5,8 @@ use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};
 use clippy_utils::{is_self, is_self_ty};
 use core::ops::ControlFlow;
 use rustc_abi::ExternAbi;
-use rustc_attr_data_structures::{AttributeKind, InlineAttr, find_attr};
+use rustc_hir::attrs::{AttributeKind, InlineAttr};
+use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
index 3497216d1c5..2cdb8ef3a65 100644
--- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
@@ -1,7 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::is_must_use_ty;
 use clippy_utils::{nth_arg, return_ty};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
index 521754f7bab..9110f684bd1 100644
--- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
+++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
@@ -168,7 +168,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
         if let Some(adt) = ty.ty_adt_def() {
             let mut iter = get_attr(
                 self.cx.sess(),
-                self.cx.tcx.get_attrs_unchecked(adt.did()),
+                self.cx.tcx.get_all_attrs(adt.did()),
                 sym::has_significant_drop,
             );
             if iter.next().is_some() {
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 216f168471e..50c44a8e75c 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::msrvs::Msrv;
-use rustc_attr_data_structures::{StabilityLevel, StableSince};
+use rustc_hir::{StabilityLevel, StableSince};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index ac92ab5a245..29931738412 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -9,6 +9,7 @@ use rustc_hir::{
     FnRetTy, HirId, Lit, PatExprKind, PatKind, QPath, StmtKind, StructTailExpr,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::ty::{FloatTy, IntTy, UintTy};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::{Ident, Symbol};
 use std::cell::Cell;
@@ -337,15 +338,43 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
             LitKind::Byte(b) => kind!("Byte({b})"),
             LitKind::Int(i, suffix) => {
                 let int_ty = match suffix {
-                    LitIntType::Signed(int_ty) => format!("LitIntType::Signed(IntTy::{int_ty:?})"),
-                    LitIntType::Unsigned(uint_ty) => format!("LitIntType::Unsigned(UintTy::{uint_ty:?})"),
+                    LitIntType::Signed(int_ty) => {
+                        let t = match int_ty {
+                            IntTy::Isize => "Isize",
+                            IntTy::I8 => "I8",
+                            IntTy::I16 => "I16",
+                            IntTy::I32 => "I32",
+                            IntTy::I64 => "I64",
+                            IntTy::I128 => "I128",
+                        };
+                        format!("LitIntType::Signed(IntTy::{t})")
+                    }
+                    LitIntType::Unsigned(uint_ty) => {
+                        let t = match uint_ty {
+                            UintTy::Usize => "Usize",
+                            UintTy::U8 => "U8",
+                            UintTy::U16 => "U16",
+                            UintTy::U32 => "U32",
+                            UintTy::U64 => "U64",
+                            UintTy::U128 => "U128",
+                        };
+                        format!("LitIntType::Unsigned(UintTy::{t})")
+                    }
                     LitIntType::Unsuffixed => String::from("LitIntType::Unsuffixed"),
                 };
                 kind!("Int({i}, {int_ty})");
             },
             LitKind::Float(_, suffix) => {
                 let float_ty = match suffix {
-                    LitFloatType::Suffixed(suffix_ty) => format!("LitFloatType::Suffixed(FloatTy::{suffix_ty:?})"),
+                    LitFloatType::Suffixed(suffix_ty) => {
+                        let t = match suffix_ty {
+                            FloatTy::F16 => "F16",
+                            FloatTy::F32 => "F32",
+                            FloatTy::F64 => "F64",
+                            FloatTy::F128 => "F128",
+                        };
+                        format!("LitFloatType::Suffixed(FloatTy::{t})")
+                    }
                     LitFloatType::Unsuffixed => String::from("LitFloatType::Unsuffixed"),
                 };
                 kind!("Float(_, {float_ty})");
diff --git a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
index 41fafc08c25..e0ae0c11cc2 100644
--- a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
@@ -2,7 +2,8 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::paths;
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_ast::{AttrStyle, DelimArgs};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{
diff --git a/src/tools/clippy/clippy_lints_internal/src/lib.rs b/src/tools/clippy/clippy_lints_internal/src/lib.rs
index 0c94d100c41..43cde86504f 100644
--- a/src/tools/clippy/clippy_lints_internal/src/lib.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/lib.rs
@@ -20,7 +20,6 @@
 #![allow(clippy::missing_clippy_version_attribute)]
 
 extern crate rustc_ast;
-extern crate rustc_attr_data_structures;
 extern crate rustc_attr_parsing;
 extern crate rustc_data_structures;
 extern crate rustc_errors;
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 34472eaab93..4ccd9c5300b 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -2,7 +2,8 @@ use crate::source::SpanRangeExt;
 use crate::{sym, tokenize_with_text};
 use rustc_ast::attr;
 use rustc_ast::attr::AttributeExt;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_errors::Applicability;
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 25afa12e95d..ecd88daa6b3 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -10,7 +10,7 @@ use crate::{clip, is_direct_expn_of, sext, unsext};
 use rustc_abi::Size;
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::{Half, Quad};
-use rustc_ast::ast::{self, LitFloatType, LitKind};
+use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
     BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
@@ -309,10 +309,10 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
         LitKind::Int(n, _) => Constant::Int(n.get()),
         LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
             // FIXME(f16_f128): just use `parse()` directly when available for `f16`/`f128`
-            ast::FloatTy::F16 => Constant::parse_f16(is.as_str()),
-            ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
-            ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),
-            ast::FloatTy::F128 => Constant::parse_f128(is.as_str()),
+            FloatTy::F16 => Constant::parse_f16(is.as_str()),
+            FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
+            FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),
+            FloatTy::F128 => Constant::parse_f128(is.as_str()),
         },
         LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect("type of float is known").kind() {
             ty::Float(FloatTy::F16) => Constant::parse_f16(is.as_str()),
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 67e09e772a7..5b9b0ef3001 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -28,7 +28,6 @@
 extern crate indexmap;
 extern crate rustc_abi;
 extern crate rustc_ast;
-extern crate rustc_attr_data_structures;
 extern crate rustc_attr_parsing;
 extern crate rustc_const_eval;
 extern crate rustc_data_structures;
@@ -91,7 +90,8 @@ use itertools::Itertools;
 use rustc_abi::Integer;
 use rustc_ast::ast::{self, LitKind, RangeLimits};
 use rustc_ast::join_path_syms;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnindexMap;
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index ba126fcd05d..60473a26493 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -42,7 +42,7 @@ pub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
     } else {
         // Allow users to tag any macro as being format!-like
         // TODO: consider deleting FORMAT_MACRO_DIAG_ITEMS and using just this method
-        get_unique_attr(cx.sess(), cx.tcx.get_attrs_unchecked(macro_def_id), sym::format_args).is_some()
+        get_unique_attr(cx.sess(), cx.tcx.get_all_attrs(macro_def_id), sym::format_args).is_some()
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 24ed4c3a8be..480e0687756 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -1,7 +1,7 @@
 use crate::sym;
 use rustc_ast::Attribute;
 use rustc_ast::attr::AttributeExt;
-use rustc_attr_data_structures::RustcVersion;
+use rustc_hir::RustcVersion;
 use rustc_attr_parsing::parse_version;
 use rustc_lint::LateContext;
 use rustc_session::Session;
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 11c17a77b15..79116eba971 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -5,7 +5,7 @@
 
 use crate::msrvs::{self, Msrv};
 use hir::LangItem;
-use rustc_attr_data_structures::{RustcVersion, StableSince};
+use rustc_hir::{RustcVersion, StableSince};
 use rustc_const_eval::check_consts::ConstCx;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -424,7 +424,7 @@ pub fn is_stable_const_fn(cx: &LateContext<'_>, def_id: DefId, msrv: Msrv) -> bo
                     .and_then(|trait_def_id| cx.tcx.lookup_const_stability(trait_def_id))
             })
             .is_none_or(|const_stab| {
-                if let rustc_attr_data_structures::StabilityLevel::Stable { since, .. } = const_stab.level {
+                if let rustc_hir::StabilityLevel::Stable { since, .. } = const_stab.level {
                     // Checking MSRV is manually necessary because `rustc` has no such concept. This entire
                     // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
                     // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index d70232ef3aa..02a8eda5893 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -6,7 +6,8 @@ use core::ops::ControlFlow;
 use itertools::Itertools;
 use rustc_abi::VariantIdx;
 use rustc_ast::ast::Mutability;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
+use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::find_attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
index 8068edfff94..c2b58b952aa 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
@@ -18,7 +18,7 @@ error: this `match` arm has a differing case than its expression
 LL |         "~!@#$%^&*()-_=+Foo" => {},
    |         ^^^^^^^^^^^^^^^^^^^^
    |
-help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference)
+help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization)
    |
 LL -         "~!@#$%^&*()-_=+Foo" => {},
 LL +         "~!@#$%^&*()-_=+foo" => {},
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index 54511f4fd08..13e694b7f03 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -203,6 +203,8 @@ pub struct TestProps {
     pub add_core_stubs: bool,
     /// Whether line annotatins are required for the given error kind.
     pub dont_require_annotations: HashSet<ErrorKind>,
+    /// Whether pretty printers should be disabled in gdb.
+    pub disable_gdb_pretty_printers: bool,
 }
 
 mod directives {
@@ -251,6 +253,7 @@ mod directives {
     pub const ADD_CORE_STUBS: &'static str = "add-core-stubs";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
+    pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers";
 }
 
 impl TestProps {
@@ -306,6 +309,7 @@ impl TestProps {
             has_enzyme: false,
             add_core_stubs: false,
             dont_require_annotations: Default::default(),
+            disable_gdb_pretty_printers: false,
         }
     }
 
@@ -654,6 +658,12 @@ impl TestProps {
                         self.dont_require_annotations
                             .insert(ErrorKind::expect_from_user_str(err_kind.trim()));
                     }
+
+                    config.set_name_directive(
+                        ln,
+                        DISABLE_GDB_PRETTY_PRINTERS,
+                        &mut self.disable_gdb_pretty_printers,
+                    );
                 },
             );
 
diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs
index 7fc76a42e0c..f7955429d83 100644
--- a/src/tools/compiletest/src/directives/directive_names.rs
+++ b/src/tools/compiletest/src/directives/directive_names.rs
@@ -18,6 +18,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "check-stdout",
     "check-test-line-numbers-match",
     "compile-flags",
+    "disable-gdb-pretty-printers",
     "doc-flags",
     "dont-check-compiler-stderr",
     "dont-check-compiler-stdout",
diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs
index 5682cc57b6f..30d8537b51a 100644
--- a/src/tools/compiletest/src/directives/tests.rs
+++ b/src/tools/compiletest/src/directives/tests.rs
@@ -203,22 +203,8 @@ impl ConfigBuilder {
         }
 
         args.push("--rustc-path".to_string());
-        // This is a subtle/fragile thing. On rust-lang CI, there is no global
-        // `rustc`, and Cargo doesn't offer a convenient way to get the path to
-        // `rustc`. Fortunately bootstrap sets `RUSTC` for us, which is pointing
-        // to the stage0 compiler.
-        //
-        // Otherwise, if you are running compiletests's tests manually, you
-        // probably don't have `RUSTC` set, in which case this falls back to the
-        // global rustc. If your global rustc is too far out of sync with stage0,
-        // then this may cause confusing errors. Or if for some reason you don't
-        // have rustc in PATH, that would also fail.
-        args.push(std::env::var("RUSTC").unwrap_or_else(|_| {
-            eprintln!(
-                "warning: RUSTC not set, using global rustc (are you not running via bootstrap?)"
-            );
-            "rustc".to_string()
-        }));
+        args.push(std::env::var("TEST_RUSTC").expect("must be configured by bootstrap"));
+
         crate::parse_config(args)
     }
 }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index f66d4f98f1f..35670ba89e9 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -354,13 +354,10 @@ impl<'test> TestCx<'test> {
             }
         } else {
             if proc_res.status.success() {
-                {
-                    self.error(&format!("{} test did not emit an error", self.config.mode));
-                    if self.config.mode == crate::common::TestMode::Ui {
-                        println!("note: by default, ui tests are expected not to compile");
-                    }
-                    proc_res.fatal(None, || ());
-                };
+                let err = &format!("{} test did not emit an error", self.config.mode);
+                let extra_note = (self.config.mode == crate::common::TestMode::Ui)
+                    .then_some("note: by default, ui tests are expected not to compile");
+                self.fatal_proc_rec_general(err, extra_note, proc_res, || ());
             }
 
             if !self.props.dont_check_failure_status {
@@ -606,7 +603,10 @@ impl<'test> TestCx<'test> {
             );
         } else {
             for pattern in missing_patterns {
-                self.error(&format!("error pattern '{}' not found!", pattern));
+                println!(
+                    "\n{prefix}: error pattern '{pattern}' not found!",
+                    prefix = self.error_prefix()
+                );
             }
             self.fatal_proc_rec("multiple error patterns not found", proc_res);
         }
@@ -765,12 +765,6 @@ impl<'test> TestCx<'test> {
         }
 
         if !unexpected.is_empty() || !not_found.is_empty() {
-            self.error(&format!(
-                "{} unexpected diagnostics reported, {} expected diagnostics not reported",
-                unexpected.len(),
-                not_found.len()
-            ));
-
             // Emit locations in a format that is short (relative paths) but "clickable" in editors.
             // Also normalize path separators to `/`.
             let file_name = self
@@ -794,19 +788,20 @@ impl<'test> TestCx<'test> {
                 |suggestions: &mut Vec<_>, e: &Error, kind, line, msg, color, rank| {
                     let mut ret = String::new();
                     if kind {
-                        ret += &format!("{} {}", "with kind".color(color), e.kind);
+                        ret += &format!("{} {}", "with different kind:".color(color), e.kind);
                     }
                     if line {
                         if !ret.is_empty() {
                             ret.push(' ');
                         }
-                        ret += &format!("{} {}", "on line".color(color), line_str(e));
+                        ret += &format!("{} {}", "on different line:".color(color), line_str(e));
                     }
                     if msg {
                         if !ret.is_empty() {
                             ret.push(' ');
                         }
-                        ret += &format!("{} {}", "with message".color(color), e.msg.cyan());
+                        ret +=
+                            &format!("{} {}", "with different message:".color(color), e.msg.cyan());
                     }
                     suggestions.push((ret, rank));
                 };
@@ -829,17 +824,21 @@ impl<'test> TestCx<'test> {
             // - only known line - meh, but suggested
             // - others are not worth suggesting
             if !unexpected.is_empty() {
-                let header = "--- reported in JSON output but not expected in test file ---";
-                println!("{}", header.green());
+                println!(
+                    "\n{prefix}: {n} diagnostics reported in JSON output but not expected in test file",
+                    prefix = self.error_prefix(),
+                    n = unexpected.len(),
+                );
                 for error in &unexpected {
                     print_error(error);
                     let mut suggestions = Vec::new();
                     for candidate in &not_found {
+                        let kind_mismatch = candidate.kind != error.kind;
                         let mut push_red_suggestion = |line, msg, rank| {
                             push_suggestion(
                                 &mut suggestions,
                                 candidate,
-                                candidate.kind != error.kind,
+                                kind_mismatch,
                                 line,
                                 msg,
                                 Color::Red,
@@ -851,26 +850,29 @@ impl<'test> TestCx<'test> {
                         } else if candidate.line_num.is_some()
                             && candidate.line_num == error.line_num
                         {
-                            push_red_suggestion(false, true, 1);
+                            push_red_suggestion(false, true, if kind_mismatch { 2 } else { 1 });
                         }
                     }
 
                     show_suggestions(suggestions, "expected", Color::Red);
                 }
-                println!("{}", "---".green());
             }
             if !not_found.is_empty() {
-                let header = "--- expected in test file but not reported in JSON output ---";
-                println!("{}", header.red());
+                println!(
+                    "\n{prefix}: {n} diagnostics expected in test file but not reported in JSON output",
+                    prefix = self.error_prefix(),
+                    n = not_found.len(),
+                );
                 for error in &not_found {
                     print_error(error);
                     let mut suggestions = Vec::new();
                     for candidate in unexpected.iter().chain(&unimportant) {
+                        let kind_mismatch = candidate.kind != error.kind;
                         let mut push_green_suggestion = |line, msg, rank| {
                             push_suggestion(
                                 &mut suggestions,
                                 candidate,
-                                candidate.kind != error.kind,
+                                kind_mismatch,
                                 line,
                                 msg,
                                 Color::Green,
@@ -882,13 +884,12 @@ impl<'test> TestCx<'test> {
                         } else if candidate.line_num.is_some()
                             && candidate.line_num == error.line_num
                         {
-                            push_green_suggestion(false, true, 1);
+                            push_green_suggestion(false, true, if kind_mismatch { 2 } else { 1 });
                         }
                     }
 
                     show_suggestions(suggestions, "reported", Color::Green);
                 }
-                println!("{}", "---".red());
             }
             panic!(
                 "errors differ from expected\nstatus: {}\ncommand: {}\n",
@@ -1996,33 +1997,52 @@ impl<'test> TestCx<'test> {
         output_base_name(self.config, self.testpaths, self.safe_revision())
     }
 
-    fn error(&self, err: &str) {
+    /// Prefix to print before error messages. Normally just `error`, but also
+    /// includes the revision name for tests that use revisions.
+    #[must_use]
+    fn error_prefix(&self) -> String {
         match self.revision {
-            Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
-            None => println!("\nerror: {}", err),
+            Some(rev) => format!("error in revision `{rev}`"),
+            None => format!("error"),
         }
     }
 
     #[track_caller]
     fn fatal(&self, err: &str) -> ! {
-        self.error(err);
+        println!("\n{prefix}: {err}", prefix = self.error_prefix());
         error!("fatal error, panic: {:?}", err);
         panic!("fatal error");
     }
 
     fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! {
-        self.error(err);
-        proc_res.fatal(None, || ());
+        self.fatal_proc_rec_general(err, None, proc_res, || ());
     }
 
-    fn fatal_proc_rec_with_ctx(
+    /// Underlying implementation of [`Self::fatal_proc_rec`], providing some
+    /// extra capabilities not needed by most callers.
+    fn fatal_proc_rec_general(
         &self,
         err: &str,
+        extra_note: Option<&str>,
         proc_res: &ProcRes,
-        on_failure: impl FnOnce(Self),
+        callback_before_unwind: impl FnOnce(),
     ) -> ! {
-        self.error(err);
-        proc_res.fatal(None, || on_failure(*self));
+        println!("\n{prefix}: {err}", prefix = self.error_prefix());
+
+        // Some callers want to print additional notes after the main error message.
+        if let Some(note) = extra_note {
+            println!("{note}");
+        }
+
+        // Print the details and output of the subprocess that caused this test to fail.
+        println!("{}", proc_res.format_info());
+
+        // Some callers want print more context or show a custom diff before the unwind occurs.
+        callback_before_unwind();
+
+        // Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
+        // compiletest, which is unnecessary noise.
+        std::panic::resume_unwind(Box::new(()));
     }
 
     // codegen tests (using FileCheck)
@@ -2081,7 +2101,7 @@ impl<'test> TestCx<'test> {
         if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" }
     }
 
-    fn compare_to_default_rustdoc(&mut self, out_dir: &Utf8Path) {
+    fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) {
         if !self.config.has_html_tidy {
             return;
         }
@@ -2958,7 +2978,8 @@ pub struct ProcRes {
 }
 
 impl ProcRes {
-    pub fn print_info(&self) {
+    #[must_use]
+    pub fn format_info(&self) -> String {
         fn render(name: &str, contents: &str) -> String {
             let contents = json::extract_rendered(contents);
             let contents = contents.trim_end();
@@ -2974,24 +2995,13 @@ impl ProcRes {
             }
         }
 
-        println!(
+        format!(
             "status: {}\ncommand: {}\n{}\n{}\n",
             self.status,
             self.cmdline,
             render("stdout", &self.stdout),
             render("stderr", &self.stderr),
-        );
-    }
-
-    pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
-        if let Some(e) = err {
-            println!("\nerror: {}", e);
-        }
-        self.print_info();
-        on_failure();
-        // Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
-        // compiletest, which is unnecessary noise.
-        std::panic::resume_unwind(Box::new(()));
+        )
     }
 }
 
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 471e4a4c819..6114afdc9df 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -259,7 +259,9 @@ impl TestCx<'_> {
                 Some(version) => {
                     println!("NOTE: compiletest thinks it is using GDB version {}", version);
 
-                    if version > extract_gdb_version("7.4").unwrap() {
+                    if !self.props.disable_gdb_pretty_printers
+                        && version > extract_gdb_version("7.4").unwrap()
+                    {
                         // Add the directory containing the pretty printers to
                         // GDB's script auto loading safe path
                         script_str.push_str(&format!(
diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs
index 236f021ce82..4a143aa5824 100644
--- a/src/tools/compiletest/src/runtest/rustdoc.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc.rs
@@ -28,8 +28,8 @@ impl TestCx<'_> {
             }
             let res = self.run_command_to_procres(&mut cmd);
             if !res.status.success() {
-                self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| {
-                    this.compare_to_default_rustdoc(&out_dir)
+                self.fatal_proc_rec_general("htmldocck failed!", None, &res, || {
+                    self.compare_to_default_rustdoc(&out_dir);
                 });
             }
         }
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index 4f35efedfde..083398f9274 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -29,9 +29,9 @@ impl TestCx<'_> {
         );
 
         if !res.status.success() {
-            self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
+            self.fatal_proc_rec_general("jsondocck failed!", None, &res, || {
                 println!("Rustdoc Output:");
-                proc_res.print_info();
+                println!("{}", proc_res.format_info());
             })
         }
 
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index ab7e35710d3..43cb1c9ae05 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1245,43 +1245,14 @@ impl ToU64 for usize {
     }
 }
 
-/// This struct is needed to enforce `#[must_use]` on values produced by [enter_trace_span] even
-/// when the "tracing" feature is not enabled.
-#[must_use]
-pub struct MaybeEnteredTraceSpan {
-    #[cfg(feature = "tracing")]
-    pub _entered_span: tracing::span::EnteredSpan,
-}
-
 /// Enters a [tracing::info_span] only if the "tracing" feature is enabled, otherwise does nothing.
-/// This is like [rustc_const_eval::enter_trace_span] except that it does not depend on the
-/// [Machine] trait to check if tracing is enabled, because from the Miri codebase we can directly
-/// check whether the "tracing" feature is enabled, unlike from the rustc_const_eval codebase.
-///
-/// In addition to the syntax accepted by [tracing::span!], this macro optionally allows passing
-/// the span name (i.e. the first macro argument) in the form `NAME::SUBNAME` (without quotes) to
-/// indicate that the span has name "NAME" (usually the name of the component) and has an additional
-/// more specific name "SUBNAME" (usually the function name). The latter is passed to the [tracing]
-/// infrastructure as a span field with the name "NAME". This allows not being distracted by
-/// subnames when looking at the trace in <https://ui.perfetto.dev>, but when deeper introspection
-/// is needed within a component, it's still possible to view the subnames directly in the UI by
-/// selecting a span, clicking on the "NAME" argument on the right, and clicking on "Visualize
-/// argument values".
-/// ```rust
-/// // for example, the first will expand to the second
-/// enter_trace_span!(borrow_tracker::on_stack_pop, /* ... */)
-/// enter_trace_span!("borrow_tracker", borrow_tracker = "on_stack_pop", /* ... */)
-/// ```
+/// This calls [rustc_const_eval::enter_trace_span] with [MiriMachine] as the first argument, which
+/// will in turn call [MiriMachine::enter_trace_span], which takes care of determining at compile
+/// time whether to trace or not (and supposedly the call is compiled out if tracing is disabled).
+/// Look at [rustc_const_eval::enter_trace_span] for complete documentation, examples and tips.
 #[macro_export]
 macro_rules! enter_trace_span {
-    ($name:ident :: $subname:ident $($tt:tt)*) => {{
-        enter_trace_span!(stringify!($name), $name = %stringify!($subname) $($tt)*)
-    }};
-
     ($($tt:tt)*) => {
-        $crate::MaybeEnteredTraceSpan {
-            #[cfg(feature = "tracing")]
-            _entered_span: tracing::info_span!($($tt)*).entered()
-        }
+        rustc_const_eval::enter_trace_span!($crate::MiriMachine<'static>, $($tt)*)
     };
 }
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 507d4f7b428..2b92c25a424 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -57,7 +57,6 @@ extern crate tracing;
 extern crate rustc_abi;
 extern crate rustc_apfloat;
 extern crate rustc_ast;
-extern crate rustc_attr_data_structures;
 extern crate rustc_const_eval;
 extern crate rustc_data_structures;
 extern crate rustc_errors;
@@ -143,9 +142,7 @@ pub use crate::eval::{
     AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, MiriEntryFnType, RejectOpWith,
     ValidationMode, create_ecx, eval_entry,
 };
-pub use crate::helpers::{
-    AccessKind, EvalContextExt as _, MaybeEnteredTraceSpan, ToU64 as _, ToUsize as _,
-};
+pub use crate::helpers::{AccessKind, EvalContextExt as _, ToU64 as _, ToUsize as _};
 pub use crate::intrinsics::EvalContextExt as _;
 pub use crate::machine::{
     AllocExtra, DynMachineCallback, FrameExtra, MachineCallback, MemoryKind, MiriInterpCx,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 8f0814a070c..00c3373bb0f 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -12,7 +12,7 @@ use rand::rngs::StdRng;
 use rand::{Rng, SeedableRng};
 use rustc_abi::{Align, ExternAbi, Size};
 use rustc_apfloat::{Float, FloatConvert};
-use rustc_attr_data_structures::InlineAttr;
+use rustc_hir::attrs::InlineAttr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 #[allow(unused)]
 use rustc_data_structures::static_assert_size;
diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs
index a889b30e145..a2bb1186944 100644
--- a/src/tools/run-make-support/src/artifact_names.rs
+++ b/src/tools/run-make-support/src/artifact_names.rs
@@ -35,6 +35,8 @@ pub fn dynamic_lib_extension() -> &'static str {
         "dylib"
     } else if target.contains("windows") {
         "dll"
+    } else if target.contains("aix") {
+        "a"
     } else {
         "so"
     }
diff --git a/src/tools/run-make-support/src/external_deps/llvm.rs b/src/tools/run-make-support/src/external_deps/llvm.rs
index 9a6e35da3fe..939160d9f41 100644
--- a/src/tools/run-make-support/src/external_deps/llvm.rs
+++ b/src/tools/run-make-support/src/external_deps/llvm.rs
@@ -60,6 +60,12 @@ pub fn llvm_pdbutil() -> LlvmPdbutil {
     LlvmPdbutil::new()
 }
 
+/// Construct a new `llvm-as` invocation. This assumes that `llvm-as` is available
+/// at `$LLVM_BIN_DIR/llvm-as`.
+pub fn llvm_as() -> LlvmAs {
+    LlvmAs::new()
+}
+
 /// Construct a new `llvm-dis` invocation. This assumes that `llvm-dis` is available
 /// at `$LLVM_BIN_DIR/llvm-dis`.
 pub fn llvm_dis() -> LlvmDis {
@@ -135,6 +141,13 @@ pub struct LlvmPdbutil {
     cmd: Command,
 }
 
+/// A `llvm-as` invocation builder.
+#[derive(Debug)]
+#[must_use]
+pub struct LlvmAs {
+    cmd: Command,
+}
+
 /// A `llvm-dis` invocation builder.
 #[derive(Debug)]
 #[must_use]
@@ -158,6 +171,7 @@ crate::macros::impl_common_helpers!(LlvmNm);
 crate::macros::impl_common_helpers!(LlvmBcanalyzer);
 crate::macros::impl_common_helpers!(LlvmDwarfdump);
 crate::macros::impl_common_helpers!(LlvmPdbutil);
+crate::macros::impl_common_helpers!(LlvmAs);
 crate::macros::impl_common_helpers!(LlvmDis);
 crate::macros::impl_common_helpers!(LlvmObjcopy);
 
@@ -441,6 +455,22 @@ impl LlvmObjcopy {
     }
 }
 
+impl LlvmAs {
+    /// Construct a new `llvm-as` invocation. This assumes that `llvm-as` is available
+    /// at `$LLVM_BIN_DIR/llvm-as`.
+    pub fn new() -> Self {
+        let llvm_as = llvm_bin_dir().join("llvm-as");
+        let cmd = Command::new(llvm_as);
+        Self { cmd }
+    }
+
+    /// Provide an input file.
+    pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+        self.cmd.arg(path.as_ref());
+        self
+    }
+}
+
 impl LlvmDis {
     /// Construct a new `llvm-dis` invocation. This assumes that `llvm-dis` is available
     /// at `$LLVM_BIN_DIR/llvm-dis`.
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 08ba1388dc1..60d3366ee98 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -173,6 +173,12 @@ impl Rustc {
         self
     }
 
+    /// This flag enables LTO in the specified form.
+    pub fn lto(&mut self, option: &str) -> &mut Self {
+        self.cmd.arg(format!("-Clto={option}"));
+        self
+    }
+
     /// This flag defers LTO optimizations to the linker.
     pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self {
         self.cmd.arg(format!("-Clinker-plugin-lto={option}"));
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 29cd6c4ad15..b7d89b130c6 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -63,8 +63,9 @@ pub use crate::external_deps::clang::{Clang, clang};
 pub use crate::external_deps::htmldocck::htmldocck;
 pub use crate::external_deps::llvm::{
     self, LlvmAr, LlvmBcanalyzer, LlvmDis, LlvmDwarfdump, LlvmFilecheck, LlvmNm, LlvmObjcopy,
-    LlvmObjdump, LlvmProfdata, LlvmReadobj, llvm_ar, llvm_bcanalyzer, llvm_dis, llvm_dwarfdump,
-    llvm_filecheck, llvm_nm, llvm_objcopy, llvm_objdump, llvm_profdata, llvm_readobj,
+    LlvmObjdump, LlvmProfdata, LlvmReadobj, llvm_ar, llvm_as, llvm_bcanalyzer, llvm_dis,
+    llvm_dwarfdump, llvm_filecheck, llvm_nm, llvm_objcopy, llvm_objdump, llvm_profdata,
+    llvm_readobj,
 };
 pub use crate::external_deps::python::python_command;
 pub use crate::external_deps::rustc::{self, Rustc, bare_rustc, rustc, rustc_path};
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index 5f30c75732c..d0eeab22062 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -156,9 +156,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
 
 [[package]]
 name = "cc"
-version = "1.2.30"
+version = "1.2.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
+checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
 dependencies = [
  "shlex",
 ]
@@ -185,9 +185,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
+checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.41"
+version = "4.5.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
+checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
 dependencies = [
  "anstream",
  "anstyle",
@@ -1343,9 +1343,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.16"
+version = "0.5.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792"
+checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
 dependencies = [
  "bitflags 2.9.1",
 ]
@@ -1459,9 +1459,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.141"
+version = "1.0.142"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
+checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
 dependencies = [
  "itoa",
  "memchr",
@@ -1969,7 +1969,7 @@ version = "0.60.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
 dependencies = [
- "windows-targets 0.53.2",
+ "windows-targets 0.53.3",
 ]
 
 [[package]]
@@ -1990,10 +1990,11 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.53.2"
+version = "0.53.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
 dependencies = [
+ "windows-link",
  "windows_aarch64_gnullvm 0.53.0",
  "windows_aarch64_msvc 0.53.0",
  "windows_i686_gnu 0.53.0",
diff --git a/src/version b/src/version
index 82e24bf241e..6979a6c0661 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.90.0
+1.91.0