about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-08 05:21:54 +0000
committerbors <bors@rust-lang.org>2024-02-08 05:21:54 +0000
commita5077d998934d0bb04bda2be1d0afe24b3170b16 (patch)
tree7d8b749d743f70a634b9d0858d733b792a41d6f9 /src
parent35551d059c17ed89aefdd0d3b4194f61fa5e312f (diff)
parent964a576dc026f4805df652776abf8a22664815be (diff)
downloadrust-a5077d998934d0bb04bda2be1d0afe24b3170b16.tar.gz
rust-a5077d998934d0bb04bda2be1d0afe24b3170b16.zip
Auto merge of #3292 - rust-lang:rustup-2024-02-08, r=saethlin
Automatic Rustup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs34
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs116
-rw-r--r--src/bootstrap/src/core/builder.rs256
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh2
-rw-r--r--src/ci/github-actions/ci.yml38
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/arm-none-eabi.md1
-rw-r--r--src/doc/rustc/src/platform-support/armv8r-none-eabihf.md40
-rw-r--r--src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md16
-rw-r--r--src/doc/unstable-book/src/library-features/async-fn-traits.md13
-rw-r--r--src/librustdoc/clean/mod.rs1
-rw-r--r--src/librustdoc/config.rs96
-rw-r--r--src/librustdoc/lib.rs41
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs1
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/scrape_examples.rs49
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs3
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.stdout4
-rw-r--r--src/tools/compiletest/src/runtest.rs1
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs2
-rw-r--r--src/tools/miri/src/machine.rs34
-rw-r--r--src/tools/miri/src/provenance_gc.rs1
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs12
-rw-r--r--src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs1
-rw-r--r--src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs6
-rw-r--r--src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs11
-rw-r--r--src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr14
-rw-r--r--src/tools/miri/tests/pass/align_offset_symbolic.rs23
-rw-r--r--src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs1
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.rs3
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs1
-rw-r--r--src/tools/rustfmt/src/parse/session.rs20
-rw-r--r--src/tools/tidy/src/ui_tests.rs5
38 files changed, 471 insertions, 383 deletions
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index ddbe18ab838..73f29d6bb6f 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -97,6 +97,20 @@ impl Std {
             is_for_mir_opt_tests: false,
         }
     }
+
+    fn copy_extra_objects(
+        &self,
+        builder: &Builder<'_>,
+        compiler: &Compiler,
+        target: TargetSelection,
+    ) -> Vec<(PathBuf, DependencyType)> {
+        let mut deps = Vec::new();
+        if !self.is_for_mir_opt_tests {
+            deps.extend(copy_third_party_objects(builder, &compiler, target));
+            deps.extend(copy_self_contained_objects(builder, &compiler, target));
+        }
+        deps
+    }
 }
 
 impl Step for Std {
@@ -159,8 +173,7 @@ impl Step for Std {
         {
             builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
 
-            copy_third_party_objects(builder, &compiler, target);
-            copy_self_contained_objects(builder, &compiler, target);
+            self.copy_extra_objects(builder, &compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler));
             return;
@@ -193,15 +206,13 @@ impl Step for Std {
 
             // Even if we're not building std this stage, the new sysroot must
             // still contain the third party objects needed by various targets.
-            copy_third_party_objects(builder, &compiler, target);
-            copy_self_contained_objects(builder, &compiler, target);
+            self.copy_extra_objects(builder, &compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler_to_use));
             return;
         }
 
-        target_deps.extend(copy_third_party_objects(builder, &compiler, target));
-        target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
+        target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
 
         // The LLD wrappers and `rust-lld` are self-contained linking components that can be
         // necessary to link the stdlib on some targets. We'll also need to copy these binaries to
@@ -222,10 +233,13 @@ impl Step for Std {
             }
         }
 
+        // We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
+        // with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
+        // fact that this is a check build integrates nicely with run_cargo.
         let mut cargo = if self.is_for_mir_opt_tests {
-            let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustc");
-            cargo.arg("-p").arg("std").arg("--crate-type=lib");
-            std_cargo(builder, target, compiler.stage, &mut cargo);
+            let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "check");
+            cargo.rustflag("-Zalways-encode-mir");
+            cargo.arg("--manifest-path").arg(builder.src.join("library/sysroot/Cargo.toml"));
             cargo
         } else {
             let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
@@ -257,7 +271,7 @@ impl Step for Std {
             vec![],
             &libstd_stamp(builder, compiler, target),
             target_deps,
-            false,
+            self.is_for_mir_opt_tests, // is_check
             false,
         );
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 04728e2e00d..baf1b5a4a1a 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -25,7 +25,6 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::flags::get_completion;
 use crate::core::config::flags::Subcommand;
 use crate::core::config::TargetSelection;
-use crate::utils;
 use crate::utils::cache::{Interned, INTERNER};
 use crate::utils::exec::BootstrapCommand;
 use crate::utils::helpers::{
@@ -38,23 +37,6 @@ use crate::{envify, CLang, DocTests, GitRepo, Mode};
 
 const ADB_TEST_DIR: &str = "/data/local/tmp/work";
 
-// mir-opt tests have different variants depending on whether a target is 32bit or 64bit, and
-// blessing them requires blessing with each target. To aid developers, when blessing the mir-opt
-// test suite the corresponding target of the opposite pointer size is also blessed.
-//
-// This array serves as the known mappings between 32bit and 64bit targets. If you're developing on
-// a target where a target with the opposite pointer size exists, feel free to add it here.
-const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[
-    // (32bit, 64bit)
-    ("i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"),
-    ("i686-unknown-linux-musl", "x86_64-unknown-linux-musl"),
-    ("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"),
-    ("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"),
-    // ARM Macs don't have a corresponding 32-bit target that they can (easily)
-    // build for, so there is no entry for "aarch64-apple-darwin" here.
-    // Likewise, i686 for macOS is no longer possible to build.
-];
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct CrateBootstrap {
     path: Interned<PathBuf>,
@@ -1487,46 +1469,18 @@ impl Step for MirOpt {
             })
         };
 
-        // We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
-        // (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
-        // When blessing, we try best-effort to also bless the other variants, to aid developers.
         if builder.config.cmd.bless() {
-            let targets = MIR_OPT_BLESS_TARGET_MAPPING
-                .iter()
-                .filter(|(target_32bit, target_64bit)| {
-                    *target_32bit == &*self.target.triple || *target_64bit == &*self.target.triple
-                })
-                .next()
-                .map(|(target_32bit, target_64bit)| {
-                    let target_32bit = TargetSelection::from_user(target_32bit);
-                    let target_64bit = TargetSelection::from_user(target_64bit);
-
-                    // Running compiletest requires a C compiler to be available, but it might not
-                    // have been detected by bootstrap if the target we're testing wasn't in the
-                    // --target flags.
-                    if !builder.cc.borrow().contains_key(&target_32bit) {
-                        utils::cc_detect::find_target(builder, target_32bit);
-                    }
-                    if !builder.cc.borrow().contains_key(&target_64bit) {
-                        utils::cc_detect::find_target(builder, target_64bit);
-                    }
+            // All that we really need to do is cover all combinations of 32/64-bit and unwind/abort,
+            // but while we're at it we might as well flex our cross-compilation support. This
+            // selection covers all our tier 1 operating systems and architectures using only tier
+            // 1 targets.
 
-                    vec![target_32bit, target_64bit]
-                })
-                .unwrap_or_else(|| {
-                    eprintln!(
-                        "\
-Note that not all variants of mir-opt tests are going to be blessed, as no mapping between
-a 32bit and a 64bit target was found for {target}.
-You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstrap/test.rs",
-                        target = self.target,
-                    );
-                    vec![self.target]
-                });
-
-            for target in targets {
-                run(target);
+            for target in ["aarch64-unknown-linux-gnu", "i686-pc-windows-msvc"] {
+                run(TargetSelection::from_user(target));
+            }
 
+            for target in ["x86_64-apple-darwin", "i686-unknown-linux-musl"] {
+                let target = TargetSelection::from_user(target);
                 let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
                     compiler: self.compiler,
                     base: target,
@@ -1616,27 +1570,27 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
                 .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target });
         }
 
-        if suite == "mir-opt" {
-            builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
-        } else {
-            builder.ensure(compile::Std::new(compiler, target));
-        }
+        // Also provide `rust_test_helpers` for the host.
+        builder.ensure(TestHelpers { target: compiler.host });
 
         // ensure that `libproc_macro` is available on the host.
         builder.ensure(compile::Std::new(compiler, compiler.host));
 
-        // Also provide `rust_test_helpers` for the host.
-        builder.ensure(TestHelpers { target: compiler.host });
-
         // As well as the target, except for plain wasm32, which can't build it
         if suite != "mir-opt" && !target.contains("wasm") && !target.contains("emscripten") {
             builder.ensure(TestHelpers { target });
         }
 
-        builder.ensure(RemoteCopyLibs { compiler, target });
-
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
 
+        if suite == "mir-opt" {
+            builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
+        } else {
+            builder.ensure(compile::Std::new(compiler, target));
+        }
+
+        builder.ensure(RemoteCopyLibs { compiler, target });
+
         // compiletest currently has... a lot of arguments, so let's just pass all
         // of them!
 
@@ -1745,11 +1699,13 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
         flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
 
-        if let Some(linker) = builder.linker(target) {
-            cmd.arg("--target-linker").arg(linker);
-        }
-        if let Some(linker) = builder.linker(compiler.host) {
-            cmd.arg("--host-linker").arg(linker);
+        if suite != "mir-opt" {
+            if let Some(linker) = builder.linker(target) {
+                cmd.arg("--target-linker").arg(linker);
+            }
+            if let Some(linker) = builder.linker(compiler.host) {
+                cmd.arg("--host-linker").arg(linker);
+            }
         }
 
         let mut hostflags = flags.clone();
@@ -1936,15 +1892,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
         }
 
-        // Running a C compiler on MSVC requires a few env vars to be set, to be
-        // sure to set them here.
-        //
-        // Note that if we encounter `PATH` we make sure to append to our own `PATH`
-        // rather than stomp over it.
-        if !builder.config.dry_run() && target.is_msvc() {
-            for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
-                if k != "PATH" {
-                    cmd.env(k, v);
+        if suite != "mir-opt" {
+            // Running a C compiler on MSVC requires a few env vars to be set, to be
+            // sure to set them here.
+            //
+            // Note that if we encounter `PATH` we make sure to append to our own `PATH`
+            // rather than stomp over it.
+            if !builder.config.dry_run() && target.is_msvc() {
+                for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
+                    if k != "PATH" {
+                        cmd.env(k, v);
+                    }
                 }
             }
         }
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index dac8393de6b..4bb8ed2fa67 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1646,76 +1646,12 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
         }
 
-        // Dealing with rpath here is a little special, so let's go into some
-        // detail. First off, `-rpath` is a linker option on Unix platforms
-        // which adds to the runtime dynamic loader path when looking for
-        // dynamic libraries. We use this by default on Unix platforms to ensure
-        // that our nightlies behave the same on Windows, that is they work out
-        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
-        // table of `config.toml`
-        //
-        // Ok, so the astute might be wondering "why isn't `-C rpath` used
-        // here?" and that is indeed a good question to ask. This codegen
-        // option is the compiler's current interface to generating an rpath.
-        // Unfortunately it doesn't quite suffice for us. The flag currently
-        // takes no value as an argument, so the compiler calculates what it
-        // should pass to the linker as `-rpath`. This unfortunately is based on
-        // the **compile time** directory structure which when building with
-        // Cargo will be very different than the runtime directory structure.
-        //
-        // All that's a really long winded way of saying that if we use
-        // `-Crpath` then the executables generated have the wrong rpath of
-        // something like `$ORIGIN/deps` when in fact the way we distribute
-        // rustc requires the rpath to be `$ORIGIN/../lib`.
-        //
-        // So, all in all, to set up the correct rpath we pass the linker
-        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
-        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
-        // to change a flag in a binary?
-        if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
-            let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
-            let rpath = if target.contains("apple") {
-                // Note that we need to take one extra step on macOS to also pass
-                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
-                // do that we pass a weird flag to the compiler to get it to do
-                // so. Note that this is definitely a hack, and we should likely
-                // flesh out rpath support more fully in the future.
-                rustflags.arg("-Zosx-rpath-install-name");
-                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
-            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
-                rustflags.arg("-Clink-args=-Wl,-z,origin");
-                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
-            } else {
-                None
-            };
-            if let Some(rpath) = rpath {
-                rustflags.arg(&format!("-Clink-args={rpath}"));
-            }
-        }
-
         cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
 
         if let Some(stack_protector) = &self.config.rust_stack_protector {
             rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
         }
 
-        for arg in linker_args(self, compiler.host, LldThreads::Yes) {
-            hostflags.arg(&arg);
-        }
-
-        if let Some(target_linker) = self.linker(target) {
-            let target = crate::envify(&target.triple);
-            cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
-        }
-        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
-        // `linker_args` here.
-        for flag in linker_flags(self, target, LldThreads::Yes) {
-            rustflags.arg(&flag);
-        }
-        for arg in linker_args(self, target, LldThreads::Yes) {
-            rustdocflags.arg(&arg);
-        }
-
         if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
         }
@@ -1731,10 +1667,6 @@ impl<'a> Builder<'a> {
         if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
             cargo.env(profile_var("OPT_LEVEL"), opt_level);
         }
-        if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
-        {
-            rustflags.arg("-Clink-arg=-gz");
-        }
         cargo.env(
             profile_var("DEBUG_ASSERTIONS"),
             if mode == Mode::Std {
@@ -1940,55 +1872,15 @@ impl<'a> Builder<'a> {
             rustflags.arg("-Wrustc::internal");
         }
 
-        // Throughout the build Cargo can execute a number of build scripts
-        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
-        // obtained previously to those build scripts.
-        // Build scripts use either the `cc` crate or `configure/make` so we pass
-        // the options through environment variables that are fetched and understood by both.
-        //
-        // FIXME: the guard against msvc shouldn't need to be here
-        if target.is_msvc() {
-            if let Some(ref cl) = self.config.llvm_clang_cl {
-                cargo.env("CC", cl).env("CXX", cl);
-            }
-        } else {
-            let ccache = self.config.ccache.as_ref();
-            let ccacheify = |s: &Path| {
-                let ccache = match ccache {
-                    Some(ref s) => s,
-                    None => return s.display().to_string(),
-                };
-                // FIXME: the cc-rs crate only recognizes the literal strings
-                // `ccache` and `sccache` when doing caching compilations, so we
-                // mirror that here. It should probably be fixed upstream to
-                // accept a new env var or otherwise work with custom ccache
-                // vars.
-                match &ccache[..] {
-                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
-                    _ => s.display().to_string(),
-                }
-            };
-            let triple_underscored = target.triple.replace("-", "_");
-            let cc = ccacheify(&self.cc(target));
-            cargo.env(format!("CC_{triple_underscored}"), &cc);
-
-            let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
-            cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
-
-            if let Some(ar) = self.ar(target) {
-                let ranlib = format!("{} s", ar.display());
-                cargo
-                    .env(format!("AR_{triple_underscored}"), ar)
-                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
-            }
-
-            if let Ok(cxx) = self.cxx(target) {
-                let cxx = ccacheify(&cxx);
-                let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
-                cargo
-                    .env(format!("CXX_{triple_underscored}"), &cxx)
-                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
-            }
+        if cmd != "check" {
+            self.configure_linker(
+                compiler,
+                target,
+                &mut cargo,
+                &mut rustflags,
+                &mut rustdocflags,
+                &mut hostflags,
+            );
         }
 
         // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
@@ -2142,6 +2034,136 @@ impl<'a> Builder<'a> {
         Cargo { command: cargo, rustflags, rustdocflags, hostflags, allow_features }
     }
 
+    fn configure_linker(
+        &self,
+        compiler: Compiler,
+        target: TargetSelection,
+        cargo: &mut Command,
+        rustflags: &mut Rustflags,
+        rustdocflags: &mut Rustflags,
+        hostflags: &mut HostFlags,
+    ) {
+        // Dealing with rpath here is a little special, so let's go into some
+        // detail. First off, `-rpath` is a linker option on Unix platforms
+        // which adds to the runtime dynamic loader path when looking for
+        // dynamic libraries. We use this by default on Unix platforms to ensure
+        // that our nightlies behave the same on Windows, that is they work out
+        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
+        // table of `config.toml`
+        //
+        // Ok, so the astute might be wondering "why isn't `-C rpath` used
+        // here?" and that is indeed a good question to ask. This codegen
+        // option is the compiler's current interface to generating an rpath.
+        // Unfortunately it doesn't quite suffice for us. The flag currently
+        // takes no value as an argument, so the compiler calculates what it
+        // should pass to the linker as `-rpath`. This unfortunately is based on
+        // the **compile time** directory structure which when building with
+        // Cargo will be very different than the runtime directory structure.
+        //
+        // All that's a really long winded way of saying that if we use
+        // `-Crpath` then the executables generated have the wrong rpath of
+        // something like `$ORIGIN/deps` when in fact the way we distribute
+        // rustc requires the rpath to be `$ORIGIN/../lib`.
+        //
+        // So, all in all, to set up the correct rpath we pass the linker
+        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
+        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
+        // to change a flag in a binary?
+        if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
+            let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
+            let rpath = if target.contains("apple") {
+                // Note that we need to take one extra step on macOS to also pass
+                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
+                // do that we pass a weird flag to the compiler to get it to do
+                // so. Note that this is definitely a hack, and we should likely
+                // flesh out rpath support more fully in the future.
+                rustflags.arg("-Zosx-rpath-install-name");
+                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
+            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
+                rustflags.arg("-Clink-args=-Wl,-z,origin");
+                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
+            } else {
+                None
+            };
+            if let Some(rpath) = rpath {
+                rustflags.arg(&format!("-Clink-args={rpath}"));
+            }
+        }
+
+        for arg in linker_args(self, compiler.host, LldThreads::Yes) {
+            hostflags.arg(&arg);
+        }
+
+        if let Some(target_linker) = self.linker(target) {
+            let target = crate::envify(&target.triple);
+            cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
+        }
+        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
+        // `linker_args` here.
+        for flag in linker_flags(self, target, LldThreads::Yes) {
+            rustflags.arg(&flag);
+        }
+        for arg in linker_args(self, target, LldThreads::Yes) {
+            rustdocflags.arg(&arg);
+        }
+
+        if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
+        {
+            rustflags.arg("-Clink-arg=-gz");
+        }
+
+        // Throughout the build Cargo can execute a number of build scripts
+        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
+        // obtained previously to those build scripts.
+        // Build scripts use either the `cc` crate or `configure/make` so we pass
+        // the options through environment variables that are fetched and understood by both.
+        //
+        // FIXME: the guard against msvc shouldn't need to be here
+        if target.is_msvc() {
+            if let Some(ref cl) = self.config.llvm_clang_cl {
+                cargo.env("CC", cl).env("CXX", cl);
+            }
+        } else {
+            let ccache = self.config.ccache.as_ref();
+            let ccacheify = |s: &Path| {
+                let ccache = match ccache {
+                    Some(ref s) => s,
+                    None => return s.display().to_string(),
+                };
+                // FIXME: the cc-rs crate only recognizes the literal strings
+                // `ccache` and `sccache` when doing caching compilations, so we
+                // mirror that here. It should probably be fixed upstream to
+                // accept a new env var or otherwise work with custom ccache
+                // vars.
+                match &ccache[..] {
+                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
+                    _ => s.display().to_string(),
+                }
+            };
+            let triple_underscored = target.triple.replace("-", "_");
+            let cc = ccacheify(&self.cc(target));
+            cargo.env(format!("CC_{triple_underscored}"), &cc);
+
+            let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
+            cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
+
+            if let Some(ar) = self.ar(target) {
+                let ranlib = format!("{} s", ar.display());
+                cargo
+                    .env(format!("AR_{triple_underscored}"), ar)
+                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
+            }
+
+            if let Ok(cxx) = self.cxx(target) {
+                let cxx = ccacheify(&cxx);
+                let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
+                cargo
+                    .env(format!("CXX_{triple_underscored}"), &cxx)
+                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
+            }
+        }
+    }
+
     /// Ensure that a given step is built, returning its output. This will
     /// cache the step, so it is safe (and good!) to call this as often as
     /// needed to ensure that all dependencies are built.
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index cc0c658aabd..f5c426a717f 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -30,7 +30,7 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt
 # We set the GC interval to the shortest possible value (0 would be off) to increase the chance
 # that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail.
 # This significantly increases the runtime of our test suite, or we'd do this in PR CI too.
-if [[ -z "${PR_CI_JOB:-}" ]]; then
+if [ -z "${PR_CI_JOB:-}" ]; then
     MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri
 else
     python3 "$X_PY" test --stage 2 src/tools/miri
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 61e0e2c0bc7..43e48c01176 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -93,7 +93,7 @@ x--expand-yaml-anchors--remove:
     <<: *base-job
 
   - &job-macos-m1
-    os: macos-13-xlarge
+    os: macos-14
     <<: *base-job
 
   - &job-windows-8c
@@ -555,16 +555,14 @@ jobs:
           # This target only needs to support 11.0 and up as nothing else supports the hardware
           - name: dist-aarch64-apple
             env:
-              SCRIPT: ./x.py dist bootstrap --include-default-paths --stage 2
+              SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin
               RUST_CONFIGURE_ARGS: >-
-                --build=x86_64-apple-darwin
-                --host=aarch64-apple-darwin
-                --target=aarch64-apple-darwin
                 --enable-full-tools
                 --enable-sanitizers
                 --enable-profiler
-                --disable-docs
                 --set rust.jemalloc
+                --set llvm.ninja=false
+                --set rust.lto=thin
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
               SELECT_XCODE: /Applications/Xcode_13.4.1.app
               USE_XCODE_CLANG: 1
@@ -574,15 +572,25 @@ jobs:
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
               DIST_REQUIRE_ALL_TOOLS: 1
-              # Corresponds to 16K page size
-              #
-              # Shouldn't be needed if jemalloc-sys is updated to
-              # handle this platform like iOS or if we build on
-              # aarch64-apple-darwin itself.
-              #
-              # https://github.com/gnzlbg/jemallocator/blob/c27a859e98e3cb790dc269773d9da71a1e918458/jemalloc-sys/build.rs#L237
-              JEMALLOC_SYS_WITH_LG_PAGE: 14
-            <<: *job-macos-xl
+            <<: *job-macos-m1
+
+          # This target only needs to support 11.0 and up as nothing else supports the hardware
+          - name: aarch64-apple
+            env:
+              SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin
+              RUST_CONFIGURE_ARGS: >-
+                --enable-sanitizers
+                --enable-profiler
+                --set rust.jemalloc
+              RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
+              SELECT_XCODE: /Applications/Xcode_13.4.1.app
+              USE_XCODE_CLANG: 1
+              MACOSX_DEPLOYMENT_TARGET: 11.0
+              MACOSX_STD_DEPLOYMENT_TARGET: 11.0
+              NO_LLVM_ASSERTIONS: 1
+              NO_DEBUG_ASSERTIONS: 1
+              NO_OVERFLOW_CHECKS: 1
+            <<: *job-macos-m1
 
           ######################
           #  Windows Builders  #
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 1998b008dc8..1f9307203bc 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -26,6 +26,7 @@
     - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
     - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
     - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md)
+    - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md)
     - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
     - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index f648a60b6c4..80d9dc85f16 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -280,6 +280,7 @@ target | std | host | notes
 [`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * |  | Bare ARMv7-A, hardfloat
 [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARMv7-A Apple WatchOS
 `armv7s-apple-ios` | ✓ |  | ARMv7-A Apple-A6 Apple iOS
+[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * |  | Bare ARMv8-R, hardfloat
 `avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
 `bpfel-unknown-none` | * |  | BPF (little endian)
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index 4f76d0d7bbc..6335a6405a1 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -13,6 +13,7 @@
 - [{arm,thumb}v4t-none-eabi](armv4t-none-eabi.md)
 - [{arm,thumb}v5te-none-eabi](armv5te-none-eabi.md)
 - armv7a-none-eabihf
+- [armv8r-none-eabihf](armv8r-none-eabihf.md)
 
 Bare-metal target for 32-bit ARM CPUs.
 
diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
new file mode 100644
index 00000000000..588e5d7c994
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
@@ -0,0 +1,40 @@
+# `armv8r-none-eabihf`
+
+**Tier: 3**
+
+Bare-metal target for CPUs in the ARMv8-R architecture family, supporting
+dual ARM/Thumb mode, with ARM mode as the default.
+
+Processors in this family include the Arm [Cortex-R52][cortex-r52]
+and [Cortex-R52+][cortex-r52-plus].
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+[cortex-r52]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52
+[cortex-r52-plus]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52-plus
+
+## Target maintainers
+
+- [Chris Copeland](https://github.com/chrisnc), `chris@chrisnc.net`
+
+## Requirements
+
+The Cortex-R52 family always includes a floating-point unit, so there is no
+non-`hf` version of this target. The floating-point features assumed by this
+target are those of the single-precision-only config of the Cortex-R52, which
+has 16 double-precision registers, accessible as 32 single-precision registers.
+The other variant of Cortex-R52 includes double-precision, 32 double-precision
+registers, and Advanced SIMD (Neon).
+
+The manual refers to this as the "Full Advanced SIMD config". To compile code
+for this variant, use: `-C target-feature=+fp64,+d32,+neon`. See the [Advanced
+SIMD and floating-point support][fpu] section of the Cortex-R52 Processor
+Technical Reference Manual for more details.
+
+[fpu]: https://developer.arm.com/documentation/100026/0104/Advanced-SIMD-and-floating-point-support/About-the-Advanced-SIMD-and-floating-point-support
+
+## Cross-compilation toolchains and C code
+
+This target supports C code compiled with the `arm-none-eabi` target triple and
+`-march=armv8-r` or a suitable `-mcpu` flag.
diff --git a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md
new file mode 100644
index 00000000000..c72df437960
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md
@@ -0,0 +1,16 @@
+# `direct_access_external_data`
+
+The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707
+
+------------------------
+
+Option `-Z direct-access-external-data` controls how to access symbols of
+external data.
+
+Supported values for this option are:
+
+- `yes` - Don't use GOT indirection to reference external data symbols.
+- `no` - Use GOT indirection to reference external data symbols.
+
+If the option is not explicitly specified, different targets have different
+default values.
diff --git a/src/doc/unstable-book/src/library-features/async-fn-traits.md b/src/doc/unstable-book/src/library-features/async-fn-traits.md
new file mode 100644
index 00000000000..e1c3f067e5b
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/async-fn-traits.md
@@ -0,0 +1,13 @@
+# `async_fn_traits`
+
+See Also: [`fn_traits`](../library-features/fn-traits.md)
+
+----
+
+The `async_fn_traits` feature allows for implementation of the [`AsyncFn*`] traits
+for creating custom closure-like types that return futures.
+
+[`AsyncFn*`]: ../../std/ops/trait.AsyncFn.html
+
+The main difference to the `Fn*` family of traits is that `AsyncFn` can return a future
+that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `AsyncFn::CallFuture` does).
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bd1d68e7074..3bac71dbc24 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2286,6 +2286,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
         }
 
         ty::Closure(..) => panic!("Closure"),
+        ty::CoroutineClosure(..) => panic!("CoroutineClosure"),
         ty::Coroutine(..) => panic!("Coroutine"),
         ty::Placeholder(..) => panic!("Placeholder"),
         ty::CoroutineWitness(..) => panic!("CoroutineWitness"),
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 3f7f9270b2d..c46047aa0db 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -323,20 +323,20 @@ impl Options {
         early_dcx: &mut EarlyDiagCtxt,
         matches: &getopts::Matches,
         args: Vec<String>,
-    ) -> Result<(Options, RenderOptions), i32> {
+    ) -> Option<(Options, RenderOptions)> {
         // Check for unstable options.
         nightly_options::check_nightly_options(early_dcx, matches, &opts());
 
         if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
             crate::usage("rustdoc");
-            return Err(0);
+            return None;
         } else if matches.opt_present("version") {
             rustc_driver::version!(&early_dcx, "rustdoc", matches);
-            return Err(0);
+            return None;
         }
 
         if rustc_driver::describe_flag_categories(early_dcx, &matches) {
-            return Err(0);
+            return None;
         }
 
         let color = config::parse_color(early_dcx, matches);
@@ -382,7 +382,7 @@ impl Options {
                 }
             }
 
-            return Err(0);
+            return None;
         }
 
         let mut emit = Vec::new();
@@ -390,10 +390,7 @@ impl Options {
             for kind in list.split(',') {
                 match kind.parse() {
                     Ok(kind) => emit.push(kind),
-                    Err(()) => {
-                        dcx.err(format!("unrecognized emission type: {kind}"));
-                        return Err(1);
-                    }
+                    Err(()) => dcx.fatal(format!("unrecognized emission type: {kind}")),
                 }
             }
         }
@@ -403,7 +400,7 @@ impl Options {
             && !matches.opt_present("show-coverage")
             && !nightly_options::is_unstable_enabled(matches)
         {
-            early_dcx.early_fatal(
+            dcx.fatal(
                 "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
             );
         }
@@ -420,10 +417,7 @@ impl Options {
             }
             let paths = match theme::load_css_paths(content) {
                 Ok(p) => p,
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             };
             let mut errors = 0;
 
@@ -442,9 +436,9 @@ impl Options {
                 }
             }
             if errors != 0 {
-                return Err(1);
+                dcx.fatal("[check-theme] one or more tests failed");
             }
-            return Err(0);
+            return None;
         }
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
@@ -452,11 +446,9 @@ impl Options {
         let input = PathBuf::from(if describe_lints {
             "" // dummy, this won't be used
         } else if matches.free.is_empty() {
-            dcx.err("missing file operand");
-            return Err(1);
+            dcx.fatal("missing file operand");
         } else if matches.free.len() > 1 {
-            dcx.err("too many file operands");
-            return Err(1);
+            dcx.fatal("too many file operands");
         } else {
             &matches.free[0]
         });
@@ -466,10 +458,7 @@ impl Options {
         let externs = parse_externs(early_dcx, matches, &unstable_opts);
         let extern_html_root_urls = match parse_extern_html_roots(matches) {
             Ok(ex) => ex,
-            Err(err) => {
-                dcx.err(err);
-                return Err(1);
-            }
+            Err(err) => dcx.fatal(err),
         };
 
         let default_settings: Vec<Vec<(String, String)>> = vec![
@@ -526,16 +515,14 @@ impl Options {
         let no_run = matches.opt_present("no-run");
 
         if !should_test && no_run {
-            dcx.err("the `--test` flag must be passed to enable `--no-run`");
-            return Err(1);
+            dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
         }
 
         let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
         let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
         let output = match (out_dir, output) {
             (Some(_), Some(_)) => {
-                dcx.err("cannot use both 'out-dir' and 'output' at once");
-                return Err(1);
+                dcx.fatal("cannot use both 'out-dir' and 'output' at once");
             }
             (Some(out_dir), None) => out_dir,
             (None, Some(output)) => output,
@@ -549,8 +536,7 @@ impl Options {
 
         if let Some(ref p) = extension_css {
             if !p.is_file() {
-                dcx.err("option --extend-css argument must be a file");
-                return Err(1);
+                dcx.fatal("option --extend-css argument must be a file");
             }
         }
 
@@ -566,31 +552,25 @@ impl Options {
             }
             let paths = match theme::load_css_paths(content) {
                 Ok(p) => p,
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             };
 
             for (theme_file, theme_s) in
                 matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned()))
             {
                 if !theme_file.is_file() {
-                    dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
+                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                         .with_help("arguments to --theme must be files")
                         .emit();
-                    return Err(1);
                 }
                 if theme_file.extension() != Some(OsStr::new("css")) {
-                    dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
+                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                         .with_help("arguments to --theme must have a .css extension")
                         .emit();
-                    return Err(1);
                 }
                 let (success, ret) = theme::test_theme_against(&theme_file, &paths, &dcx);
                 if !success {
-                    dcx.err(format!("error loading theme file: \"{theme_s}\""));
-                    return Err(1);
+                    dcx.fatal(format!("error loading theme file: \"{theme_s}\""));
                 } else if !ret.is_empty() {
                     dcx.struct_warn(format!(
                         "theme file \"{theme_s}\" is missing CSS rules from the default theme",
@@ -620,22 +600,18 @@ impl Options {
             edition,
             &None,
         ) else {
-            return Err(3);
+            dcx.fatal("`ExternalHtml::load` failed");
         };
 
         match matches.opt_str("r").as_deref() {
             Some("rust") | None => {}
-            Some(s) => {
-                dcx.err(format!("unknown input format: {s}"));
-                return Err(1);
-            }
+            Some(s) => dcx.fatal(format!("unknown input format: {s}")),
         }
 
         let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
         if let Some(ref index_page) = index_page {
             if !index_page.is_file() {
-                dcx.err("option `--index-page` argument must be a file");
-                return Err(1);
+                dcx.fatal("option `--index-page` argument must be a file");
             }
         }
 
@@ -646,8 +622,7 @@ impl Options {
         let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
             Ok(types) => types,
             Err(e) => {
-                dcx.err(format!("unknown crate type: {e}"));
-                return Err(1);
+                dcx.fatal(format!("unknown crate type: {e}"));
             }
         };
 
@@ -655,18 +630,13 @@ impl Options {
             Some(s) => match OutputFormat::try_from(s.as_str()) {
                 Ok(out_fmt) => {
                     if !out_fmt.is_json() && show_coverage {
-                        dcx.struct_err(
+                        dcx.fatal(
                             "html output format isn't supported for the --show-coverage option",
-                        )
-                        .emit();
-                        return Err(1);
+                        );
                     }
                     out_fmt
                 }
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             },
             None => OutputFormat::default(),
         };
@@ -709,16 +679,14 @@ impl Options {
         let html_no_source = matches.opt_present("html-no-source");
 
         if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
-            dcx.struct_err(
+            dcx.fatal(
                 "--generate-link-to-definition option can only be used with HTML output format",
-            )
-            .emit();
-            return Err(1);
+            );
         }
 
-        let scrape_examples_options = ScrapeExamplesOptions::new(matches, &dcx)?;
+        let scrape_examples_options = ScrapeExamplesOptions::new(matches, &dcx);
         let with_examples = matches.opt_strs("with-examples");
-        let call_locations = crate::scrape_examples::load_call_locations(with_examples, &dcx)?;
+        let call_locations = crate::scrape_examples::load_call_locations(with_examples, &dcx);
 
         let unstable_features =
             rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
@@ -793,7 +761,7 @@ impl Options {
             no_emit_shared: false,
             html_no_source,
         };
-        Ok((options, render_options))
+        Some((options, render_options))
     }
 
     /// Returns `true` if the file given as `self.input` is a Markdown file.
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8c10f14116a..097bbeb6d28 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -177,13 +177,16 @@ pub fn main() {
     init_logging(&early_dcx);
     rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
 
-    let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&early_dcx) {
-        Some(args) => main_args(&mut early_dcx, &args, using_internal_features),
-        _ =>
-        {
-            #[allow(deprecated)]
-            Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
-        }
+    let exit_code = rustc_driver::catch_with_exit_code(|| {
+        let args = env::args_os()
+            .enumerate()
+            .map(|(i, arg)| {
+                arg.into_string().unwrap_or_else(|arg| {
+                    early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}"))
+                })
+            })
+            .collect::<Vec<_>>();
+        main_args(&mut early_dcx, &args, using_internal_features)
     });
     process::exit(exit_code);
 }
@@ -219,19 +222,6 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) {
     tracing::subscriber::set_global_default(subscriber).unwrap();
 }
 
-fn get_args(early_dcx: &EarlyDiagCtxt) -> Option<Vec<String>> {
-    env::args_os()
-        .enumerate()
-        .map(|(i, arg)| {
-            arg.into_string()
-                .map_err(|arg| {
-                    early_dcx.early_warn(format!("Argument {i} is not valid Unicode: {arg:?}"));
-                })
-                .ok()
-        })
-        .collect()
-}
-
 fn opts() -> Vec<RustcOptGroup> {
     let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
     let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
@@ -730,15 +720,8 @@ fn main_args(
     // Note that we discard any distinction between different non-zero exit
     // codes from `from_matches` here.
     let (options, render_options) = match config::Options::from_matches(early_dcx, &matches, args) {
-        Ok(opts) => opts,
-        Err(code) => {
-            return if code == 0 {
-                Ok(())
-            } else {
-                #[allow(deprecated)]
-                Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
-            };
-        }
+        Some(opts) => opts,
+        None => return Ok(()),
     };
 
     let diag =
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a75d9bee304..fe02611b5d4 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -503,6 +503,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             }
             ty::Alias(..)
             | ty::Closure(..)
+            | ty::CoroutineClosure(..)
             | ty::Coroutine(..)
             | ty::CoroutineWitness(..)
             | ty::Dynamic(..)
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index e73649c7224..6649894f9c2 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -156,7 +156,7 @@ impl Translate for BufferEmitter {
 }
 
 impl Emitter for BufferEmitter {
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+    fn emit_diagnostic(&mut self, diag: Diagnostic) {
         let mut buffer = self.buffer.borrow_mut();
 
         let fluent_args = to_fluent_args(diag.args());
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index b7d9c16f348..9c9b386edda 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -38,28 +38,23 @@ pub(crate) struct ScrapeExamplesOptions {
 }
 
 impl ScrapeExamplesOptions {
-    pub(crate) fn new(
-        matches: &getopts::Matches,
-        dcx: &rustc_errors::DiagCtxt,
-    ) -> Result<Option<Self>, i32> {
+    pub(crate) fn new(matches: &getopts::Matches, dcx: &rustc_errors::DiagCtxt) -> Option<Self> {
         let output_path = matches.opt_str("scrape-examples-output-path");
         let target_crates = matches.opt_strs("scrape-examples-target-crate");
         let scrape_tests = matches.opt_present("scrape-tests");
         match (output_path, !target_crates.is_empty(), scrape_tests) {
-            (Some(output_path), true, _) => Ok(Some(ScrapeExamplesOptions {
+            (Some(output_path), true, _) => Some(ScrapeExamplesOptions {
                 output_path: PathBuf::from(output_path),
                 target_crates,
                 scrape_tests,
-            })),
+            }),
             (Some(_), false, _) | (None, true, _) => {
-                dcx.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
-                Err(1)
+                dcx.fatal("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
             }
             (None, false, true) => {
-                dcx.err("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
-                Err(1)
+                dcx.fatal("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
             }
-            (None, false, false) => Ok(None),
+            (None, false, false) => None,
         }
     }
 }
@@ -342,24 +337,20 @@ pub(crate) fn run(
 pub(crate) fn load_call_locations(
     with_examples: Vec<String>,
     dcx: &rustc_errors::DiagCtxt,
-) -> Result<AllCallLocations, i32> {
-    let inner = || {
-        let mut all_calls: AllCallLocations = FxHashMap::default();
-        for path in with_examples {
-            let bytes = fs::read(&path).map_err(|e| format!("{e} (for path {path})"))?;
-            let mut decoder = MemDecoder::new(&bytes, 0);
-            let calls = AllCallLocations::decode(&mut decoder);
-
-            for (function, fn_calls) in calls.into_iter() {
-                all_calls.entry(function).or_default().extend(fn_calls.into_iter());
-            }
-        }
+) -> AllCallLocations {
+    let mut all_calls: AllCallLocations = FxHashMap::default();
+    for path in with_examples {
+        let bytes = match fs::read(&path) {
+            Ok(bytes) => bytes,
+            Err(e) => dcx.fatal(format!("failed to load examples: {e}")),
+        };
+        let mut decoder = MemDecoder::new(&bytes, 0);
+        let calls = AllCallLocations::decode(&mut decoder);
 
-        Ok(all_calls)
-    };
+        for (function, fn_calls) in calls.into_iter() {
+            all_calls.entry(function).or_default().extend(fn_calls.into_iter());
+        }
+    }
 
-    inner().map_err(|e: String| {
-        dcx.err(format!("failed to load examples: {e}"));
-        1
-    })
+    all_calls
 }
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 1ef8cf7de3c..808fb0c07ea 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -83,6 +83,7 @@ static TARGETS: &[&str] = &[
     "armebv7r-none-eabihf",
     "armv7r-none-eabi",
     "armv7r-none-eabihf",
+    "armv8r-none-eabihf",
     "armv7s-apple-ios",
     "bpfeb-unknown-none",
     "bpfel-unknown-none",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject cdf84b69d0416c57ac9dc3459af80dfb4883d27
+Subproject ccc84ccec4b7340eb916aefda1cb3e2fe17d8e7
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 8ff54dfcfa0..194cf69ea7e 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -881,6 +881,7 @@ impl TyCoercionStability {
                 | ty::Coroutine(..)
                 | ty::CoroutineWitness(..)
                 | ty::Closure(..)
+                | ty::CoroutineClosure(..)
                 | ty::Never
                 | ty::Tuple(_)
                 | ty::Alias(ty::Projection, _) => Self::Deref,
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index b26ebe5cee3..288df0fd663 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -490,6 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                             format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
                         },
                     },
+                    ClosureKind::CoroutineClosure(desugaring) => format!(
+                        "ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})"
+                    ),
                 };
 
                 let ret_ty = match fn_decl.output {
diff --git a/src/tools/clippy/tests/ui/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout
index 8c4d71e68f8..579f137f861 100644
--- a/src/tools/clippy/tests/ui/author/blocks.stdout
+++ b/src/tools/clippy/tests/ui/author/blocks.stdout
@@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind
 {
     // report your lint here
 }
-if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = expr.kind
+if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind
     && let FnRetTy::DefaultReturn(_) = fn_decl.output
     && expr1 = &cx.tcx.hir().body(body_id).value
-    && let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
+    && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
     && let FnRetTy::DefaultReturn(_) = fn_decl1.output
     && expr2 = &cx.tcx.hir().body(body_id1).value
     && let ExprKind::Block(block, None) = expr2.kind
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8be4def15de..ed1c559e1f6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2467,6 +2467,7 @@ impl<'test> TestCx<'test> {
                     "-Zvalidate-mir",
                     "-Zlint-mir",
                     "-Zdump-mir-exclude-pass-number",
+                    "--crate-type=rlib",
                 ]);
                 if let Some(pass) = &self.props.mir_unit_test {
                     rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]);
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index f3e10689ff1..17e50400cec 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-f3b9d47a46c6d237665801155aa3e26c5f49958b
+384b02c0825cefa59f2e8a99a33d9a5344959079
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index c5cd78ad665..f50aaa292fd 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -382,7 +382,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // will never cause UB on the pointer itself.
             let (_, _, kind) = this.get_alloc_info(*alloc_id);
             if matches!(kind, AllocKind::LiveData) {
-                let alloc_extra = this.get_alloc_extra(*alloc_id).unwrap();
+                let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
                 let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
                 alloc_borrow_tracker.release_protector(&this.machine, borrow_tracker, *tag)?;
             }
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 946887637ff..40d041c8fdb 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -2,7 +2,7 @@
 //! `Machine` trait.
 
 use std::borrow::Cow;
-use std::cell::{Cell, RefCell};
+use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::fmt;
 use std::path::Path;
@@ -336,20 +336,11 @@ pub struct AllocExtra<'tcx> {
     /// if this allocation is leakable. The backtrace is not
     /// pruned yet; that should be done before printing it.
     pub backtrace: Option<Vec<FrameInfo<'tcx>>>,
-    /// An offset inside this allocation that was deemed aligned even for symbolic alignment checks.
-    /// Invariant: the promised alignment will never be less than the native alignment of this allocation.
-    pub symbolic_alignment: Cell<Option<(Size, Align)>>,
 }
 
 impl VisitProvenance for AllocExtra<'_> {
     fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
-        let AllocExtra {
-            borrow_tracker,
-            data_race,
-            weak_memory,
-            backtrace: _,
-            symbolic_alignment: _,
-        } = self;
+        let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self;
 
         borrow_tracker.visit_provenance(visit);
         data_race.visit_provenance(visit);
@@ -572,6 +563,14 @@ pub struct MiriMachine<'mir, 'tcx> {
     /// that is fixed per stack frame; this lets us have sometimes different results for the
     /// same const while ensuring consistent results within a single call.
     const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx, Provenance>>>,
+
+    /// For each allocation, an offset inside that allocation that was deemed aligned even for
+    /// symbolic alignment checks. This cannot be stored in `AllocExtra` since it needs to be
+    /// tracked for vtables and function allocations as well as regular allocations.
+    ///
+    /// Invariant: the promised alignment will never be less than the native alignment of the
+    /// allocation.
+    pub(crate) symbolic_alignment: RefCell<FxHashMap<AllocId, (Size, Align)>>,
 }
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
@@ -698,6 +697,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
             collect_leak_backtraces: config.collect_leak_backtraces,
             allocation_spans: RefCell::new(FxHashMap::default()),
             const_cache: RefCell::new(FxHashMap::default()),
+            symbolic_alignment: RefCell::new(FxHashMap::default()),
         }
     }
 
@@ -810,6 +810,7 @@ impl VisitProvenance for MiriMachine<'_, '_> {
             collect_leak_backtraces: _,
             allocation_spans: _,
             const_cache: _,
+            symbolic_alignment: _,
         } = self;
 
         threads.visit_provenance(visit);
@@ -893,9 +894,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
             return None;
         }
         // Let's see which alignment we have been promised for this allocation.
-        let alloc_info = ecx.get_alloc_extra(alloc_id).unwrap(); // cannot fail since the allocation is live
-        let (promised_offset, promised_align) =
-            alloc_info.symbolic_alignment.get().unwrap_or((Size::ZERO, alloc_align));
+        let (promised_offset, promised_align) = ecx
+            .machine
+            .symbolic_alignment
+            .borrow()
+            .get(&alloc_id)
+            .copied()
+            .unwrap_or((Size::ZERO, alloc_align));
         if promised_align < align {
             // Definitely not enough.
             Some(Misalignment { has: promised_align, required: align })
@@ -1132,7 +1137,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
                 data_race: race_alloc,
                 weak_memory: buffer_alloc,
                 backtrace,
-                symbolic_alignment: Cell::new(None),
             },
             |ptr| ecx.global_base_pointer(ptr),
         )?;
diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs
index ab178f82d9f..347951ce372 100644
--- a/src/tools/miri/src/provenance_gc.rs
+++ b/src/tools/miri/src/provenance_gc.rs
@@ -196,6 +196,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_mut();
         let allocs = LiveAllocs { ecx: this, collected: allocs };
         this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id));
+        this.machine.symbolic_alignment.borrow_mut().retain(|id, _| allocs.is_live(*id));
         this.machine.intptrcast.borrow_mut().remove_unreachable_allocs(&allocs);
         if let Some(borrow_tracker) = &this.machine.borrow_tracker {
             borrow_tracker.borrow_mut().remove_unreachable_allocs(&allocs);
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index dd3e8efb6ef..f4d69055344 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -583,17 +583,17 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 }
                 if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr) {
                     let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
-                    // Not `get_alloc_extra_mut`, need to handle read-only allocations!
-                    let alloc_extra = this.get_alloc_extra(alloc_id)?;
                     // If the newly promised alignment is bigger than the native alignment of this
                     // allocation, and bigger than the previously promised alignment, then set it.
                     if align > alloc_align
-                        && !alloc_extra
+                        && !this
+                            .machine
                             .symbolic_alignment
-                            .get()
-                            .is_some_and(|(_, old_align)| align <= old_align)
+                            .get_mut()
+                            .get(&alloc_id)
+                            .is_some_and(|&(_, old_align)| align <= old_align)
                     {
-                        alloc_extra.symbolic_alignment.set(Some((offset, align)));
+                        this.machine.symbolic_alignment.get_mut().insert(alloc_id, (offset, align));
                     }
                 }
             }
diff --git a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
index 0e7c3dbcc04..13f913454dc 100644
--- a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
+++ b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
@@ -1,4 +1,5 @@
 trait T1 {
+    #[allow(dead_code)]
     fn method1(self: Box<Self>);
 }
 trait T2 {
diff --git a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
index 648ac07c43e..982f33b0a31 100644
--- a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
+++ b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
@@ -2,30 +2,36 @@
 #![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
+    #[allow(dead_code)]
     fn a(&self) -> i32 {
         10
     }
 
+    #[allow(dead_code)]
     fn z(&self) -> i32 {
         11
     }
 
+    #[allow(dead_code)]
     fn y(&self) -> i32 {
         12
     }
 }
 
 trait Bar: Foo {
+    #[allow(dead_code)]
     fn b(&self) -> i32 {
         20
     }
 
+    #[allow(dead_code)]
     fn w(&self) -> i32 {
         21
     }
 }
 
 trait Baz: Bar {
+    #[allow(dead_code)]
     fn c(&self) -> i32 {
         30
     }
diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
new file mode 100644
index 00000000000..fef5a6cddb9
--- /dev/null
+++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
@@ -0,0 +1,11 @@
+//@compile-flags: -Zmiri-symbolic-alignment-check
+
+extern "C" {
+    static _dispatch_queue_attr_concurrent: [u8; 0];
+}
+
+static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] = unsafe { &_dispatch_queue_attr_concurrent };
+
+fn main() {
+    let _val = *DISPATCH_QUEUE_CONCURRENT; //~ERROR: is not supported
+}
diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr
new file mode 100644
index 00000000000..a4249d2e881
--- /dev/null
+++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
+  --> $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
+   |
+LL |     let _val = *DISPATCH_QUEUE_CONCURRENT;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs
index 4df364bac7a..ac28c63e081 100644
--- a/src/tools/miri/tests/pass/align_offset_symbolic.rs
+++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs
@@ -1,6 +1,8 @@
 //@compile-flags: -Zmiri-symbolic-alignment-check
 #![feature(strict_provenance)]
 
+use std::mem;
+
 fn test_align_to() {
     const N: usize = 4;
     let d = Box::new([0u32; N]);
@@ -68,7 +70,7 @@ fn test_u64_array() {
     #[repr(align(8))]
     struct AlignToU64<T>(T);
 
-    const BYTE_LEN: usize = std::mem::size_of::<[u64; 4]>();
+    const BYTE_LEN: usize = mem::size_of::<[u64; 4]>();
     type Data = AlignToU64<[u8; BYTE_LEN]>;
 
     fn example(data: &Data) {
@@ -101,10 +103,29 @@ fn huge_align() {
     let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
 }
 
+// This shows that we cannot store the promised alignment info in `AllocExtra`,
+// since vtables do not have an `AllocExtra`.
+fn vtable() {
+    #[cfg(target_pointer_width = "64")]
+    type TWOPTR = u128;
+    #[cfg(target_pointer_width = "32")]
+    type TWOPTR = u64;
+
+    let ptr: &dyn Send = &0;
+    let parts: (*const (), *const u8) = unsafe { mem::transmute(ptr) };
+    let vtable = parts.1;
+    let offset = vtable.align_offset(mem::align_of::<TWOPTR>());
+    let _vtable_aligned = vtable.wrapping_add(offset) as *const [TWOPTR; 0];
+    // FIXME: we can't actually do the access since vtable pointers act like zero-sized allocations.
+    // Enable the next line once https://github.com/rust-lang/rust/issues/117945 is implemented.
+    //let _place = unsafe { &*vtable_aligned };
+}
+
 fn main() {
     test_align_to();
     test_from_utf8();
     test_u64_array();
     test_cstr();
     huge_align();
+    vtable();
 }
diff --git a/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs b/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
index ccf96b99672..2491bda0917 100644
--- a/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
+++ b/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
@@ -9,6 +9,7 @@ trait Foo<T> {
     }
 }
 
+#[allow(dead_code)]
 trait Bar {
     fn bar(&self) {
         println!("Bar!");
diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs
index 8432012a9ba..529b9c471d4 100644
--- a/src/tools/miri/tests/pass/dyn-upcast.rs
+++ b/src/tools/miri/tests/pass/dyn-upcast.rs
@@ -383,14 +383,17 @@ fn struct_() {
 
 fn replace_vptr() {
     trait A {
+        #[allow(dead_code)]
         fn foo_a(&self);
     }
 
     trait B {
+        #[allow(dead_code)]
         fn foo_b(&self);
     }
 
     trait C: A + B {
+        #[allow(dead_code)]
         fn foo_c(&self);
     }
 
diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs
index 4c3be6b3559..e10ccc277f6 100644
--- a/src/tools/miri/tests/pass/weak_memory/weak.rs
+++ b/src/tools/miri/tests/pass/weak_memory/weak.rs
@@ -11,6 +11,7 @@ use std::sync::atomic::Ordering::*;
 use std::sync::atomic::{fence, AtomicUsize};
 use std::thread::spawn;
 
+#[allow(dead_code)]
 #[derive(Copy, Clone)]
 struct EvilSend<T>(pub T);
 
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 6dc3eac44d4..f0af401d3da 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -47,7 +47,7 @@ impl Emitter for SilentEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+    fn emit_diagnostic(&mut self, _db: Diagnostic) {}
 }
 
 fn silent_emitter() -> Box<DynEmitter> {
@@ -64,7 +64,7 @@ struct SilentOnIgnoredFilesEmitter {
 }
 
 impl SilentOnIgnoredFilesEmitter {
-    fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) {
+    fn handle_non_ignoreable_error(&mut self, db: Diagnostic) {
         self.has_non_ignorable_parser_errors = true;
         self.can_reset.store(false, Ordering::Release);
         self.emitter.emit_diagnostic(db);
@@ -86,7 +86,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, db: &Diagnostic) {
+    fn emit_diagnostic(&mut self, db: Diagnostic) {
         if db.level() == DiagnosticLevel::Fatal {
             return self.handle_non_ignoreable_error(db);
         }
@@ -365,7 +365,7 @@ mod tests {
                 None
             }
 
-            fn emit_diagnostic(&mut self, _db: &Diagnostic) {
+            fn emit_diagnostic(&mut self, _db: Diagnostic) {
                 self.num_emitted_errors.fetch_add(1, Ordering::Release);
             }
         }
@@ -424,7 +424,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span));
-            emitter.emit_diagnostic(&fatal_diagnostic);
+            emitter.emit_diagnostic(fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
@@ -449,7 +449,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            emitter.emit_diagnostic(non_fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), true);
         }
@@ -473,7 +473,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            emitter.emit_diagnostic(non_fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
@@ -512,9 +512,9 @@ mod tests {
             let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span));
             let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span));
             let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None);
-            emitter.emit_diagnostic(&bar_diagnostic);
-            emitter.emit_diagnostic(&foo_diagnostic);
-            emitter.emit_diagnostic(&fatal_diagnostic);
+            emitter.emit_diagnostic(bar_diagnostic);
+            emitter.emit_diagnostic(foo_diagnostic);
+            emitter.emit_diagnostic(fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 451276b5ac1..4a44c40debd 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -13,8 +13,9 @@ use std::path::{Path, PathBuf};
 // desirable, because large numbers of files are unwieldy in general. See issue
 // #73494.
 const ENTRY_LIMIT: usize = 900;
-const ISSUES_ENTRY_LIMIT: usize = 1807;
-const ROOT_ENTRY_LIMIT: usize = 870;
+// FIXME: The following limits should be reduced eventually.
+const ISSUES_ENTRY_LIMIT: usize = 1819;
+const ROOT_ENTRY_LIMIT: usize = 871;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files