about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@users.noreply.github.com>2025-05-01 07:33:30 +0000
committerGitHub <noreply@github.com>2025-05-01 07:33:30 +0000
commit00d2f60efd516bc7ea658bd0a6de5e2f1f1df322 (patch)
tree9375885343e27ab26b20dfe5a3714e00d5d378d0 /src
parente7502210ce5ab2d92cb87c372dab51b637ba6df4 (diff)
parent1c5de64814d72effc6890ca823fa4d248041a0bd (diff)
downloadrust-00d2f60efd516bc7ea658bd0a6de5e2f1f1df322.tar.gz
rust-00d2f60efd516bc7ea658bd0a6de5e2f1f1df322.zip
Merge pull request #19726 from lnicola/sync-from-rust
Sync from downstream again
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs2
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs14
-rw-r--r--src/bootstrap/src/core/config/config.rs8
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/tests/git.rs3
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh2
-rw-r--r--src/ci/github-actions/jobs.yml10
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh123
-rw-r--r--src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml2
-rw-r--r--src/doc/rustc-dev-guide/README.md4
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md5
-rw-r--r--src/doc/rustc-dev-guide/src/autodiff/installation.md12
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md4
-rw-r--r--src/doc/rustc-dev-guide/src/git.md59
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md6
-rw-r--r--src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md2
-rw-r--r--src/doc/unstable-book/src/language-features/deref-patterns.md15
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs8
-rw-r--r--src/librustdoc/doctest/make.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs5
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr2
-rw-r--r--src/tools/compiletest/src/common.rs8
-rw-r--r--src/tools/compiletest/src/errors.rs35
-rw-r--r--src/tools/compiletest/src/executor.rs1
-rw-r--r--src/tools/compiletest/src/executor/libtest.rs111
-rw-r--r--src/tools/compiletest/src/header.rs2
-rw-r--r--src/tools/compiletest/src/json.rs8
-rw-r--r--src/tools/compiletest/src/lib.rs19
-rw-r--r--src/tools/compiletest/src/runtest.rs22
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs6
-rw-r--r--src/tools/miri/.github/workflows/ci.yml72
-rw-r--r--src/tools/miri/README.md2
-rw-r--r--src/tools/miri/bench-cargo-miri/mse/src/main.rs2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs111
-rw-r--r--src/tools/miri/src/bin/miri.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs15
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/src/helpers.rs2
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs27
-rw-r--r--src/tools/miri/src/machine.rs15
-rw-r--r--src/tools/miri/src/math.rs26
-rw-r--r--src/tools/miri/src/shims/time.rs33
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs433
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs17
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs5
-rw-r--r--src/tools/miri/src/shims/windows/fs.rs19
-rw-r--r--src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs9
-rw-r--r--src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs9
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs6
-rw-r--r--src/tools/miri/tests/fail/no_main.stderr2
-rw-r--r--src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs2
-rw-r--r--src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr4
-rw-r--r--src/tools/miri/tests/pass-dep/shims/windows-fs.rs25
-rw-r--r--src/tools/miri/tests/pass/async-drop.rs107
-rw-r--r--src/tools/miri/tests/pass/async-drop.stack.stdout37
-rw-r--r--src/tools/miri/tests/pass/async-drop.tree.stdout37
-rw-r--r--src/tools/miri/tests/pass/dst-raw.rs2
-rw-r--r--src/tools/miri/tests/pass/float.rs119
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs2
-rw-r--r--src/tools/miri/tests/pass/slices.rs3
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs2
-rw-r--r--src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs178
-rw-r--r--src/tools/rust-analyzer/Cargo.lock12
-rw-r--r--src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rustfmt/src/pairs.rs14
-rw-r--r--src/tools/rustfmt/src/types.rs13
-rw-r--r--src/tools/rustfmt/tests/source/let_chains.rs10
-rw-r--r--src/tools/rustfmt/tests/target/let_chains.rs8
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
99 files changed, 1284 insertions, 785 deletions
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 1549d4713af..ac568eab2e8 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -462,7 +462,7 @@ macro_rules! bootstrap_tool {
     }
 }
 
-pub(crate) const COMPILETEST_ALLOW_FEATURES: &str = "test,internal_output_capture";
+pub(crate) const COMPILETEST_ALLOW_FEATURES: &str = "internal_output_capture";
 
 bootstrap_tool!(
     // This is marked as an external tool because it includes dependencies
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index e4503b26456..36b3c95d638 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -872,11 +872,15 @@ impl Builder<'_> {
         }
         cargo.env(
             profile_var("DEBUG_ASSERTIONS"),
-            if mode == Mode::Std {
-                self.config.std_debug_assertions.to_string()
-            } else {
-                self.config.rustc_debug_assertions.to_string()
-            },
+            match mode {
+                Mode::Std => self.config.std_debug_assertions,
+                Mode::Rustc => self.config.rustc_debug_assertions,
+                Mode::Codegen => self.config.rustc_debug_assertions,
+                Mode::ToolBootstrap => self.config.tools_debug_assertions,
+                Mode::ToolStd => self.config.tools_debug_assertions,
+                Mode::ToolRustc => self.config.tools_debug_assertions,
+            }
+            .to_string(),
         );
         cargo.env(
             profile_var("OVERFLOW_CHECKS"),
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 23b623d9bab..65a3e7667e7 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -306,6 +306,7 @@ pub struct Config {
 
     pub rustc_debug_assertions: bool,
     pub std_debug_assertions: bool,
+    pub tools_debug_assertions: bool,
 
     pub rust_overflow_checks: bool,
     pub rust_overflow_checks_std: bool,
@@ -1280,6 +1281,7 @@ define_config! {
         rustc_debug_assertions: Option<bool> = "debug-assertions",
         randomize_layout: Option<bool> = "randomize-layout",
         std_debug_assertions: Option<bool> = "debug-assertions-std",
+        tools_debug_assertions: Option<bool> = "debug-assertions-tools",
         overflow_checks: Option<bool> = "overflow-checks",
         overflow_checks_std: Option<bool> = "overflow-checks-std",
         debug_logging: Option<bool> = "debug-logging",
@@ -1937,6 +1939,7 @@ impl Config {
         let mut debug = None;
         let mut rustc_debug_assertions = None;
         let mut std_debug_assertions = None;
+        let mut tools_debug_assertions = None;
         let mut overflow_checks = None;
         let mut overflow_checks_std = None;
         let mut debug_logging = None;
@@ -2000,6 +2003,7 @@ impl Config {
                 codegen_units_std,
                 rustc_debug_assertions: rustc_debug_assertions_toml,
                 std_debug_assertions: std_debug_assertions_toml,
+                tools_debug_assertions: tools_debug_assertions_toml,
                 overflow_checks: overflow_checks_toml,
                 overflow_checks_std: overflow_checks_std_toml,
                 debug_logging: debug_logging_toml,
@@ -2084,6 +2088,7 @@ impl Config {
             debug = debug_toml;
             rustc_debug_assertions = rustc_debug_assertions_toml;
             std_debug_assertions = std_debug_assertions_toml;
+            tools_debug_assertions = tools_debug_assertions_toml;
             overflow_checks = overflow_checks_toml;
             overflow_checks_std = overflow_checks_std_toml;
             debug_logging = debug_logging_toml;
@@ -2509,6 +2514,8 @@ impl Config {
         let default = debug == Some(true);
         config.rustc_debug_assertions = rustc_debug_assertions.unwrap_or(default);
         config.std_debug_assertions = std_debug_assertions.unwrap_or(config.rustc_debug_assertions);
+        config.tools_debug_assertions =
+            tools_debug_assertions.unwrap_or(config.rustc_debug_assertions);
         config.rust_overflow_checks = overflow_checks.unwrap_or(default);
         config.rust_overflow_checks_std =
             overflow_checks_std.unwrap_or(config.rust_overflow_checks);
@@ -3568,6 +3575,7 @@ fn check_incompatible_options_for_ci_rustc(
         codegen_units_std: _,
         rustc_debug_assertions: _,
         std_debug_assertions: _,
+        tools_debug_assertions: _,
         overflow_checks: _,
         overflow_checks_std: _,
         debuginfo_level: _,
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 3f1885a425f..d926185ffaf 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -401,4 +401,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "Added new option `include` to create config extensions.",
     },
+    ChangeInfo {
+        change_id: 140438,
+        severity: ChangeSeverity::Info,
+        summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/tests/git.rs b/src/bootstrap/src/utils/tests/git.rs
index bd40f398c7b..d9dd9ab9800 100644
--- a/src/bootstrap/src/utils/tests/git.rs
+++ b/src/bootstrap/src/utils/tests/git.rs
@@ -129,6 +129,9 @@ impl GitCtx {
 
     fn git_cmd(&self) -> Command {
         let mut cmd = Command::new("git");
+        cmd.env("GIT_CONFIG_NOSYSTEM", "1");
+        cmd.env("GIT_CONFIG_SYSTEM", "/tmp/nonexistent");
+        cmd.env("GIT_CONFIG_GLOBAL", "/tmp/nonexistent");
         cmd.current_dir(&self.dir);
         cmd
     }
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index ae5bf8946dd..bedf45c8630 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -2,7 +2,7 @@
 # CentOS 7 has headers for kernel 3.10, but that's fine as long as we don't
 # actually use newer APIs in rustc or std without a fallback. It's more
 # important that we match glibc for ELF symbol versioning.
-FROM centos:7
+FROM ghcr.io/rust-lang/centos:7
 
 WORKDIR /build
 
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index ea8066d95e0..1d280948ebe 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -2,7 +2,7 @@
 
 set -euo pipefail
 
-LINUX_VERSION=v6.14-rc3
+LINUX_VERSION=v6.15-rc4
 
 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt
 ../x.py build --stage 2 library rustdoc clippy rustfmt
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 88b29d2df56..afcc092e78e 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -65,6 +65,12 @@ runners:
     os: codebuild-ubuntu-22-36c-$github.run_id-$github.run_attempt
     <<: *base-job
 
+  - &job-linux-8c-codebuild
+    free_disk: true
+    codebuild: true
+    os: codebuild-ubuntu-22-8c-$github.run_id-$github.run_attempt
+    <<: *base-job
+
 envs:
   env-x86_64-apple-tests: &env-x86_64-apple-tests
     SCRIPT: ./x.py check compiletest --set build.compiletest-use-stage0-libtest=true && ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc -- --exact
@@ -160,7 +166,7 @@ auto:
     <<: *job-linux-4c
 
   - name: dist-arm-linux
-    <<: *job-linux-36c-codebuild
+    <<: *job-linux-8c-codebuild
 
   - name: dist-armhf-linux
     <<: *job-linux-4c
@@ -213,7 +219,7 @@ auto:
   - name: dist-x86_64-linux
     env:
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-linux-16c
+    <<: *job-linux-36c-codebuild
 
   - name: dist-x86_64-linux-alt
     env:
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index ad7ee136e9c..173f64858b3 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -87,59 +87,80 @@ printDF() {
 
 removeUnusedFilesAndDirs() {
     local to_remove=(
-        "/usr/local/aws-sam-cli"
-        "/usr/local/doc/cmake"
-        "/usr/local/julia"*
-        "/usr/local/lib/android"
-        "/usr/local/share/chromedriver-"*
-        "/usr/local/share/chromium"
-        "/usr/local/share/cmake-"*
-        "/usr/local/share/edge_driver"
-        "/usr/local/share/gecko_driver"
-        "/usr/local/share/icons"
-        "/usr/local/share/vim"
-        "/usr/local/share/emacs"
-        "/usr/local/share/powershell"
-        "/usr/local/share/vcpkg"
-        "/usr/share/apache-maven-"*
-        "/usr/share/gradle-"*
         "/usr/share/java"
-        "/usr/share/kotlinc"
-        "/usr/share/miniconda"
-        "/usr/share/php"
-        "/usr/share/ri"
-        "/usr/share/swift"
-
-        # binaries
-        "/usr/local/bin/azcopy"
-        "/usr/local/bin/bicep"
-        "/usr/local/bin/ccmake"
-        "/usr/local/bin/cmake-"*
-        "/usr/local/bin/cmake"
-        "/usr/local/bin/cpack"
-        "/usr/local/bin/ctest"
-        "/usr/local/bin/helm"
-        "/usr/local/bin/kind"
-        "/usr/local/bin/kustomize"
-        "/usr/local/bin/minikube"
-        "/usr/local/bin/packer"
-        "/usr/local/bin/phpunit"
-        "/usr/local/bin/pulumi-"*
-        "/usr/local/bin/pulumi"
-        "/usr/local/bin/stack"
-
-        # Haskell runtime
-        "/usr/local/.ghcup"
-
-        # Azure
-        "/opt/az"
-        "/usr/share/az_"*
     )
 
-    if [ -n "${AGENT_TOOLSDIRECTORY:-}" ]; then
-        # Environment variable set by GitHub Actions
+    if isGitHubRunner; then
+        to_remove+=(
+            "/usr/local/aws-sam-cli"
+            "/usr/local/doc/cmake"
+            "/usr/local/julia"*
+            "/usr/local/lib/android"
+            "/usr/local/share/chromedriver-"*
+            "/usr/local/share/chromium"
+            "/usr/local/share/cmake-"*
+            "/usr/local/share/edge_driver"
+            "/usr/local/share/emacs"
+            "/usr/local/share/gecko_driver"
+            "/usr/local/share/icons"
+            "/usr/local/share/powershell"
+            "/usr/local/share/vcpkg"
+            "/usr/local/share/vim"
+            "/usr/share/apache-maven-"*
+            "/usr/share/gradle-"*
+            "/usr/share/kotlinc"
+            "/usr/share/miniconda"
+            "/usr/share/php"
+            "/usr/share/ri"
+            "/usr/share/swift"
+
+            # binaries
+            "/usr/local/bin/azcopy"
+            "/usr/local/bin/bicep"
+            "/usr/local/bin/ccmake"
+            "/usr/local/bin/cmake-"*
+            "/usr/local/bin/cmake"
+            "/usr/local/bin/cpack"
+            "/usr/local/bin/ctest"
+            "/usr/local/bin/helm"
+            "/usr/local/bin/kind"
+            "/usr/local/bin/kustomize"
+            "/usr/local/bin/minikube"
+            "/usr/local/bin/packer"
+            "/usr/local/bin/phpunit"
+            "/usr/local/bin/pulumi-"*
+            "/usr/local/bin/pulumi"
+            "/usr/local/bin/stack"
+
+            # Haskell runtime
+            "/usr/local/.ghcup"
+
+            # Azure
+            "/opt/az"
+            "/usr/share/az_"*
+        )
+
+        if [ -n "${AGENT_TOOLSDIRECTORY:-}" ]; then
+            # Environment variable set by GitHub Actions
+            to_remove+=(
+                "${AGENT_TOOLSDIRECTORY}"
+            )
+        else
+            echo "::warning::AGENT_TOOLSDIRECTORY is not set. Skipping removal."
+        fi
+    else
+        # Remove folders and files present in AWS CodeBuild
         to_remove+=(
-            "${AGENT_TOOLSDIRECTORY}"
+            # binaries
+            "/usr/local/bin/ecs-cli"
+            "/usr/local/bin/eksctl"
+            "/usr/local/bin/kubectl"
+
+            "${HOME}/.gradle"
+            "${HOME}/.dotnet"
+            "${HOME}/.goenv"
+            "${HOME}/.phpenv"
+
         )
     fi
 
@@ -194,6 +215,10 @@ cleanPackages() {
                 'powershell'
             )
         fi
+    else
+        packages+=(
+            'google-chrome-stable'
+        )
     fi
 
     sudo apt-get -qq remove -y --fix-missing "${packages[@]}"
diff --git a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
index b19eccf9eb8..1e430d8b4e6 100644
--- a/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
+++ b/src/doc/rustc-dev-guide/.github/workflows/rustc-pull.yml
@@ -28,7 +28,7 @@ jobs:
           # Cache the josh directory with checked out rustc
           cache-directories: "/home/runner/.cache/rustc-dev-guide-josh"
       - name: Install josh
-        run: RUSTFLAGS="--cap-lints warn" cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
+        run: RUSTFLAGS="--cap-lints warn" cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
       - name: Setup bot git name and email
         run: |
           git config --global user.name 'The rustc-dev-guide Cronjob Bot'
diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md
index 9f468b933d7..08158801788 100644
--- a/src/doc/rustc-dev-guide/README.md
+++ b/src/doc/rustc-dev-guide/README.md
@@ -77,7 +77,7 @@ This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.g
 You'll need to install `josh-proxy` locally via
 
 ```
-cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
+cargo install josh-proxy --git https://github.com/josh-project/josh --tag r24.10.04
 ```
 Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version.
 
@@ -106,5 +106,5 @@ You may observe "Nothing to pull" even if you *know* rustc-pull has something to
 To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g.
 
 ```
-GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull
+GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull
 ```
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index dc52e0928cc..67fa25f2228 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-b8005bff3248cfc6e327faf4fa631ac49bb49ba9
+deb947971c8748f5c6203548ce4af9022f21eaf0
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 68112d06167..d6ec803a60a 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -1,6 +1,7 @@
 # Summary
 
 [Getting Started](./getting-started.md)
+
 [About this guide](./about-this-guide.md)
 
 ---
@@ -231,9 +232,13 @@
 ---
 
 [Appendix A: Background topics](./appendix/background.md)
+
 [Appendix B: Glossary](./appendix/glossary.md)
+
 [Appendix C: Code Index](./appendix/code-index.md)
+
 [Appendix D: Compiler Lecture Series](./appendix/compiler-lecture.md)
+
 [Appendix E: Bibliography](./appendix/bibliography.md)
 
 [Appendix Z: HumorRust](./appendix/humorust.md)
diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md
index dbea9dbe144..f3c11395523 100644
--- a/src/doc/rustc-dev-guide/src/autodiff/installation.md
+++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md
@@ -25,9 +25,10 @@ rustup toolchain install nightly # enables -Z unstable-options
 You can then run our test cases:
 
 ```bash
-./x.py test --stage 1 library tests/ui/autodiff
-./x.py test --stage 1 library tests/codegen/autodiff
-./x.py test --stage 1 library tests/pretty/autodiff*
+./x.py test --stage 1 tests/codegen/autodiff
+./x.py test --stage 1 tests/pretty/autodiff
+./x.py test --stage 1 tests/ui/autodiff
+./x.py test --stage 1 tests/ui/feature-gates/feature-gate-autodiff.rs
 ```
 
 Autodiff is still experimental, so if you want to use it in your own projects, you will need to add `lto="fat"` to your Cargo.toml 
@@ -44,7 +45,7 @@ apt install wget vim python3 git curl libssl-dev pkg-config lld ninja-build cmak
 ```
 Then build rustc in a slightly altered way:
 ```bash
-git clone --depth=1 https://github.com/EnzymeAD/rust.git
+git clone --depth=1 https://github.com/rust-lang/rust.git
 cd rust
 ./configure --enable-llvm-link-shared --enable-llvm-plugins --enable-llvm-enzyme --release-channel=nightly --enable-llvm-assertions --enable-clang --enable-lld --enable-option-checking --enable-ninja --disable-docs
 ./x dist
@@ -54,7 +55,8 @@ We then copy the tarball to our host. The dockerid is the newest entry under `do
 docker cp <dockerid>:/rust/build/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz rust-nightly-x86_64-unknown-linux-gnu.tar.gz
 ```
 Afterwards we can create a new (pre-release) tag on the EnzymeAD/rust repository and make a PR against the EnzymeAD/enzyme-explorer repository to update the tag.
-Remember to ping `tgymnich` on the PR to run his update script.
+Remember to ping `tgymnich` on the PR to run his update script. Note: We should archive EnzymeAD/rust and update the instructions here. The explorer should soon
+be able to get the rustc toolchain from the official rust servers.
 
 
 ## Build instruction for Enzyme itself
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
index 1dd5402f4cd..ffcfe259625 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/what-bootstrapping-does.md
@@ -394,8 +394,8 @@ will be rare to want to use it. Finally, `MAGIC_EXTRA_RUSTFLAGS` bypasses the
   this is `compiletest`. For unit tests and doc tests this is the `libtest`
   runner.
 
-Most test runner accept `--help`, which you can use to find out the options
-accepted by the runner.
+Most test runners accept `--help`,
+which you can use to find out the options accepted by the runner.
 
 ## Environment Variables
 
diff --git a/src/doc/rustc-dev-guide/src/git.md b/src/doc/rustc-dev-guide/src/git.md
index 177495b5362..8118ddff10c 100644
--- a/src/doc/rustc-dev-guide/src/git.md
+++ b/src/doc/rustc-dev-guide/src/git.md
@@ -38,13 +38,13 @@ If you've cloned your fork, then you will be able to reference it with `origin`
 in your local repo. It may be helpful to also set up a remote for the official
 rust-lang/rust repo via
 
-```sh
+```console
 git remote add upstream https://github.com/rust-lang/rust.git
 ```
 
 if you're using HTTPS, or
 
-```sh
+```console
 git remote add upstream git@github.com:rust-lang/rust.git
 ```
 
@@ -112,7 +112,7 @@ See [Rebasing](#rebasing) for more about rebasing.
 This is not a problem from git's perspective. If you run `git remote -v`,
 it will say something like this:
 
-```
+```console
 $ git remote -v
 origin  git@github.com:jyn514/rust.git (fetch)
 origin  git@github.com:jyn514/rust.git (push)
@@ -158,11 +158,11 @@ To fix it, do the following things:
 ### I see "error: cannot rebase" when I try to rebase
 
 These are two common errors to see when rebasing:
-```
+```console
 error: cannot rebase: Your index contains uncommitted changes.
 error: Please commit or stash them.
 ```
-```
+```console
 error: cannot rebase: You have unstaged changes.
 error: Please commit or stash them.
 ```
@@ -174,7 +174,7 @@ commit your changes, or make a temporary commit called a "stash" to have them st
 when you finish rebasing. You may want to configure git to make this "stash" automatically, which
 will prevent the "cannot rebase" error in nearly all cases:
 
-```
+```console
 git config --global rebase.autostash true
 ```
 
@@ -205,7 +205,7 @@ git reset --hard master
 
 `git push` will not work properly and say something like this:
 
-```
+```console
  ! [rejected]        issue-xxxxx -> issue-xxxxx (non-fast-forward)
 error: failed to push some refs to 'https://github.com/username/rust.git'
 hint: Updates were rejected because the tip of your current branch is behind
@@ -226,7 +226,7 @@ didn't write, it likely means you're trying to rebase over the wrong branch. For
 have a `rust-lang/rust` remote `upstream`, but ran `git rebase origin/master` instead of `git rebase
 upstream/master`. The fix is to abort the rebase and use the correct branch instead:
 
-```
+```console
 git rebase --abort
 git rebase -i upstream/master
 ```
@@ -243,7 +243,7 @@ When updating your local repository with `git pull`, you may notice that sometim
 Git says you have modified some files that you have never edited. For example,
 running `git status` gives you something like (note the `new commits` mention):
 
-```
+```console
 On branch master
 Your branch is up to date with 'origin/master'.
 
@@ -256,9 +256,12 @@ Changes not staged for commit:
 no changes added to commit (use "git add" and/or "git commit -a")
 ```
 
-These changes are not changes to files: they are changes to submodules (more on this
-[later](#git-submodules)). To get rid of those, run `./x --help`, which will automatically update
-the submodules.
+These changes are not changes to files: they are changes to submodules (more on this [later](#git-submodules)).
+To get rid of those:
+
+```console
+git submodule update
+```
 
 Some submodules are not actually needed; for example, `src/llvm-project` doesn't need to be checked
 out if you're using `download-ci-llvm`.  To avoid having to keep fetching its history, you can use
@@ -278,12 +281,12 @@ merged. To do that, you need to rebase your work on top of rust-lang/rust.
 To rebase your feature branch on top of the newest version of the master branch
 of rust-lang/rust, checkout your branch, and then run this command:
 
-```
+```console
 git pull --rebase https://github.com/rust-lang/rust.git master
 ```
 
 > If you are met with the following error:
-> ```
+> ```console
 > error: cannot pull with rebase: Your index contains uncommitted changes.
 > error: please commit or stash them.
 > ```
@@ -300,13 +303,13 @@ reapply the changes fails because your changes conflicted with other changes
 that have been made. You can tell that this happened because you'll see
 lines in the output that look like
 
-```
+```console
 CONFLICT (content): Merge conflict in file.rs
 ```
 
 When you open these files, you'll see sections of the form
 
-```
+```console
 <<<<<<< HEAD
 Original code
 =======
@@ -346,7 +349,7 @@ will keep it up-to-date. You will also want to rebase your feature branches
 up-to-date as well. After pulling, you can checkout the feature branches
 and rebase them:
 
-```
+```console
 git checkout master
 git pull upstream master --ff-only # to make certain there are no merge commits
 git rebase master feature_branch
@@ -384,7 +387,7 @@ change the order in which they are applied, or "squash" them into each other.
 
 Alternatively, you can sacrifice the commit history like this:
 
-```
+```console
 # squash all the changes into one commit so you only have to worry about conflicts once
 git rebase -i --keep-base master  # and squash all changes along the way
 git rebase master
@@ -422,7 +425,7 @@ it shows you the differences between your old diff and your new diff.
 Here's an example of `git range-diff` output (taken from [Git's
 docs][range-diff-example-docs]):
 
-```
+```console
 -:  ------- > 1:  0ddba11 Prepare for the inevitable!
 1:  c0debee = 2:  cab005e Add a helpful message at the start
 2:  f00dbal ! 3:  decafe1 Describe a bug
@@ -499,7 +502,7 @@ Git and Github's default diff view for large moves *within* a file is quite poor
 line as deleted and each line as added, forcing you to compare each line yourself. Git has an option
 to show moved lines in a different color:
 
-```
+```console
 git log -p --color-moved=dimmed-zebra --color-moved-ws=allow-indentation-change
 ```
 
@@ -515,7 +518,7 @@ that was force-pushed to make sure there are no unexpected changes.
 Many large files in the repo are autogenerated. To view a diff that ignores changes to those files,
 you can use the following syntax (e.g. Cargo.lock):
 
-```
+```console
 git log -p ':!Cargo.lock'
 ```
 
@@ -545,7 +548,7 @@ The contents of submodules are ignored by Git: submodules are in some sense isol
 from the rest of the repository. However, if you try to `cd src/llvm-project` and then
 run `git status`:
 
-```
+```console
 HEAD detached at 9567f08afc943
 nothing to commit, working tree clean
 ```
@@ -576,7 +579,7 @@ that Git can nicely and fairly conveniently handle for us.
 
 Sometimes you might run into (when you run `git status`)
 
-```
+```console
 Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
@@ -586,7 +589,7 @@ Changes not staged for commit:
 
 and when you try to run `git submodule update` it breaks horribly with errors like
 
-```
+```console
 error: RPC failed; curl 92 HTTP/2 stream 7 was not closed cleanly: CANCEL (err 8)
 error: 2782 bytes of body are still expected
 fetch-pack: unexpected disconnect while reading sideband packet
@@ -597,8 +600,8 @@ fatal: Fetched in submodule path 'src/llvm-project', but it did not contain 5a51
 
 If you see `(new commits, modified content)` you can run
 
-```bash
-$ git submodule foreach git reset --hard
+```console
+git submodule foreach git reset --hard
 ```
 
 and then try `git submodule update` again.
@@ -607,7 +610,7 @@ and then try `git submodule update` again.
 
 If that doesn't work, you can try to deinit all git submodules...
 
-```
+```console
 git submodule deinit -f --all
 ```
 
@@ -618,7 +621,7 @@ completely messed up for some reason.
 
 Sometimes, for some forsaken reason, you might run into
 
-```text
+```console
 fatal: not a git repository: src/gcc/../../.git/modules/src/gcc
 ```
 
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 6232c8bcc0a..b31c861c947 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -372,9 +372,9 @@ E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively.
 Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like
 target-dependent compiler output.
 
-Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away.
-They will match any compiler output kind, but will not force exhaustive annotations for that kind.
-Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect.
+Some diagnostics are never required to be line-annotated, regardless of their kind or directives,
+for example secondary lines of multiline diagnostics,
+or ubiquitous diagnostics like `aborting due to N previous errors`.
 
 UI tests use the `-A unused` flag by default to ignore all unused warnings, as
 unused warnings are usually not the focus of a test. However, simple code
diff --git a/src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md b/src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
index 6895f232238..1520b86341b 100644
--- a/src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
+++ b/src/doc/unstable-book/src/compiler-flags/rustc-bootstrap.md
@@ -23,7 +23,7 @@ Crates can fully opt out of unstable features by using [`#![forbid(unstable_feat
 In particular, nightly is built with beta, and beta is built with stable.
 Since the standard library and compiler both use unstable features, `RUSTC_BOOTSTRAP` is required so that we can use the previous version to build them.
 
-## Why is this environment variable so easy to use for people not in the rust project?
+## Why is this environment variable so easy to use for people not in the Rust project?
 
 Originally, `RUSTC_BOOTSTRAP` required passing in a hash of the previous compiler version, to discourage using it for any purpose other than bootstrapping.
 That constraint was later relaxed; see <https://github.com/rust-lang/rust/issues/36548> for the discussion that happened at that time.
diff --git a/src/doc/unstable-book/src/language-features/deref-patterns.md b/src/doc/unstable-book/src/language-features/deref-patterns.md
index d0a64538e8c..0cc7106da48 100644
--- a/src/doc/unstable-book/src/language-features/deref-patterns.md
+++ b/src/doc/unstable-book/src/language-features/deref-patterns.md
@@ -7,7 +7,7 @@ The tracking issue for this feature is: [#87121]
 ------------------------
 
 > **Note**: This feature is incomplete. In the future, it is meant to supersede
-> [`box_patterns`](./box-patterns.md) and [`string_deref_patterns`](./string-deref-patterns.md).
+> [`box_patterns`] and [`string_deref_patterns`].
 
 This feature permits pattern matching on [smart pointers in the standard library] through their
 `Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which
@@ -54,6 +54,17 @@ if let [b] = &mut *v {
 assert_eq!(v, [Box::new(Some(2))]);
 ```
 
+Like [`box_patterns`], deref patterns may move out of boxes:
+
+```rust
+# #![feature(deref_patterns)]
+# #![allow(incomplete_features)]
+struct NoCopy;
+// Match exhaustiveness analysis is not yet implemented.
+let deref!(x) = Box::new(NoCopy) else { unreachable!() };
+drop::<NoCopy>(x);
+```
+
 Additionally, when `deref_patterns` is enabled, string literal patterns may be written where `str`
 is expected. Likewise, byte string literal patterns may be written where `[u8]` or `[u8; _]` is
 expected. This lets them be used in `deref!(_)` patterns:
@@ -75,4 +86,6 @@ match *"test" {
 
 Implicit deref pattern syntax is not yet supported for string or byte string literals.
 
+[`box_patterns`]: ./box-patterns.md
+[`string_deref_patterns`]: ./string-deref-patterns.md
 [smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6ecb67c776c..622a410837b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2213,9 +2213,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
             }))
         }
 
-        ty::Alias(ty::Weak, data) => {
+        ty::Alias(ty::Free, data) => {
             if cx.tcx.features().lazy_type_alias() {
-                // Weak type alias `data` represents the `type X` in `type X = Y`. If we need `Y`,
+                // Free type alias `data` represents the `type X` in `type X = Y`. If we need `Y`,
                 // we need to use `type_of`.
                 let path = clean_middle_path(
                     cx,
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index fc99dd08b78..e967fd40609 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -34,20 +34,20 @@ pub(super) fn render_macro_matcher(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Stri
     //             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
     //         ) => {...};
     //     }
-    printer.cbox(8);
+    let cb = printer.cbox(8);
     printer.word("(");
     printer.zerobreak();
-    printer.ibox(0);
+    let ib = printer.ibox(0);
     match matcher {
         TokenTree::Delimited(_span, _spacing, _delim, tts) => print_tts(&mut printer, tts),
         // Matcher which is not a Delimited is unexpected and should've failed
         // to compile, but we render whatever it is wrapped in parens.
         TokenTree::Token(..) => print_tt(&mut printer, matcher),
     }
-    printer.end();
+    printer.end(ib);
     printer.break_offset_if_not_bol(0, -4);
     printer.word(")");
-    printer.end();
+    printer.end(cb);
     printer.s.eof()
 }
 
diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs
index d5c965f7053..4194abc8d57 100644
--- a/src/librustdoc/doctest/make.rs
+++ b/src/librustdoc/doctest/make.rs
@@ -407,17 +407,27 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                     push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
                 }
             }
+            let mut has_non_items = false;
             for stmt in &body.stmts {
                 let mut is_extern_crate = false;
                 match stmt.kind {
                     StmtKind::Item(ref item) => {
                         is_extern_crate = check_item(&item, &mut info, crate_name);
                     }
-                    StmtKind::Expr(ref expr) if matches!(expr.kind, ast::ExprKind::Err(_)) => {
-                        reset_error_count(&psess);
-                        return Err(());
+                    StmtKind::Expr(ref expr) => {
+                        if matches!(expr.kind, ast::ExprKind::Err(_)) {
+                            reset_error_count(&psess);
+                            return Err(());
+                        }
+                        has_non_items = true;
                     }
-                    StmtKind::MacCall(ref mac_call) if !info.has_main_fn => {
+                    // We assume that the macro calls will expand to item(s) even though they could
+                    // expand to statements and expressions. And the simple fact that we're trying
+                    // to retrieve a `main` function inside it is a terrible idea.
+                    StmtKind::MacCall(ref mac_call) => {
+                        if info.has_main_fn {
+                            continue;
+                        }
                         let mut iter = mac_call.mac.args.tokens.iter();
 
                         while let Some(token) = iter.next() {
@@ -437,7 +447,9 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                             }
                         }
                     }
-                    _ => {}
+                    _ => {
+                        has_non_items = true;
+                    }
                 }
 
                 // Weirdly enough, the `Stmt` span doesn't include its attributes, so we need to
@@ -462,6 +474,11 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
                     push_to_s(&mut info.crates, source, span, &mut prev_span_hi);
                 }
             }
+            if has_non_items {
+                // FIXME: if `info.has_main_fn` is `true`, emit a warning here to mention that
+                // this code will not be called.
+                info.has_main_fn = false;
+            }
             Ok(info)
         }
         Err(e) => {
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 7da5a530eaa..5edb5c23570 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -853,7 +853,7 @@ impl TyCoercionStability {
                     continue;
                 },
                 ty::Param(_) if for_return => Self::Deref,
-                ty::Alias(ty::Weak | ty::Inherent, _) => unreachable!("should have been normalized away above"),
+                ty::Alias(ty::Free | ty::Inherent, _) => unreachable!("should have been normalized away above"),
                 ty::Alias(ty::Projection, _) if !for_return && ty.has_non_region_param() => Self::Reborrow,
                 ty::Infer(_)
                 | ty::Error(_)
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 67537a251da..1f142bc3ba6 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -197,7 +197,7 @@ fn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool
     inputs.iter().any(|input| {
         matches!(
             input.kind(),
-            ty::Alias(ty::AliasTyKind::Weak, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait()
+            ty::Alias(ty::AliasTyKind::Free, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait()
         )
     })
 }
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index fe1fd70a9fa..17368a7530d 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1117,6 +1117,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_const_arg(s);
                 self.hash_const_arg(e);
             },
+            TyPatKind::Or(variants) => {
+                for variant in variants.iter() {
+                    self.hash_ty_pat(variant)
+                }
+            },
             TyPatKind::Err(_) => {},
         }
     }
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index bdac1e42309..ad3c420270c 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -236,7 +236,7 @@ LL |     if result.is_ok() {
 LL |         result.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: creating a shared reference to mutable static is discouraged
+error: creating a shared reference to mutable static
   --> tests/ui/checked_unwrap/simple_conditionals.rs:183:12
    |
 LL |         if X.is_some() {
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index e0132056d6c..4f93b498741 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -413,14 +413,6 @@ pub struct Config {
     /// cross-compilation scenarios that do not otherwise want/need to `-Zbuild-std`. Used in e.g.
     /// ABI tests.
     pub minicore_path: Utf8PathBuf,
-
-    /// If true, disable the "new" executor, and use the older libtest-based
-    /// executor to run tests instead. This is a temporary fallback, to make
-    /// manual comparative testing easier if bugs are found in the new executor.
-    ///
-    /// FIXME(Zalathar): Eventually remove this flag and remove the libtest
-    /// dependency.
-    pub no_new_executor: bool,
 }
 
 impl Config {
diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs
index 3bb98276bf5..a45f39b036c 100644
--- a/src/tools/compiletest/src/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
@@ -30,24 +30,20 @@ impl ErrorKind {
 
     /// Either the canonical uppercase string, or some additional versions for compatibility.
     /// FIXME: consider keeping only the canonical versions here.
-    fn from_user_str(s: &str) -> Option<ErrorKind> {
-        Some(match s {
+    pub fn from_user_str(s: &str) -> ErrorKind {
+        match s {
             "HELP" | "help" => ErrorKind::Help,
             "ERROR" | "error" => ErrorKind::Error,
-            "NOTE" | "note" => ErrorKind::Note,
+            // `MONO_ITEM` makes annotations in `codegen-units` tests syntactically correct,
+            // but those tests never use the error kind later on.
+            "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note,
             "SUGGESTION" => ErrorKind::Suggestion,
             "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning,
-            _ => return None,
-        })
-    }
-
-    pub fn expect_from_user_str(s: &str) -> ErrorKind {
-        ErrorKind::from_user_str(s).unwrap_or_else(|| {
-            panic!(
+            _ => panic!(
                 "unexpected diagnostic kind `{s}`, expected \
                  `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
-            )
-        })
+            ),
+        }
     }
 }
 
@@ -67,8 +63,7 @@ impl fmt::Display for ErrorKind {
 pub struct Error {
     pub line_num: Option<usize>,
     /// What kind of message we expect (e.g., warning, error, suggestion).
-    /// `None` if not specified or unknown message kind.
-    pub kind: Option<ErrorKind>,
+    pub kind: ErrorKind,
     pub msg: String,
     /// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations
     /// are not mandatory, even if they would otherwise be mandatory for primary errors.
@@ -79,12 +74,7 @@ pub struct Error {
 impl Error {
     pub fn render_for_expected(&self) -> String {
         use colored::Colorize;
-        format!(
-            "{: <10}line {: >3}: {}",
-            self.kind.map(|kind| kind.to_string()).unwrap_or_default(),
-            self.line_num_str(),
-            self.msg.cyan(),
-        )
+        format!("{: <10}line {: >3}: {}", self.kind, self.line_num_str(), self.msg.cyan())
     }
 
     pub fn line_num_str(&self) -> String {
@@ -173,9 +163,10 @@ fn parse_expected(
     // Get the part of the comment after the sigil (e.g. `~^^` or ~|).
     let tag = captures.get(0).unwrap();
     let rest = line[tag.end()..].trim_start();
-    let (kind_str, _) = rest.split_once(|c: char| !c.is_ascii_alphabetic()).unwrap_or((rest, ""));
+    let (kind_str, _) =
+        rest.split_once(|c: char| c != '_' && !c.is_ascii_alphabetic()).unwrap_or((rest, ""));
     let kind = ErrorKind::from_user_str(kind_str);
-    let untrimmed_msg = if kind.is_some() { &rest[kind_str.len()..] } else { rest };
+    let untrimmed_msg = &rest[kind_str.len()..];
     let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned();
 
     let line_num_adjust = &captures["adjust"];
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
index 990be56ce0c..e774c5e2047 100644
--- a/src/tools/compiletest/src/executor.rs
+++ b/src/tools/compiletest/src/executor.rs
@@ -12,7 +12,6 @@ use crate::common::{Config, TestPaths};
 
 mod deadline;
 mod json;
-pub(crate) mod libtest;
 
 pub(crate) fn run_tests(config: &Config, tests: Vec<CollectedTest>) -> bool {
     let tests_len = tests.len();
diff --git a/src/tools/compiletest/src/executor/libtest.rs b/src/tools/compiletest/src/executor/libtest.rs
deleted file mode 100644
index 032b3f4fa9a..00000000000
--- a/src/tools/compiletest/src/executor/libtest.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-//! This submodule encapsulates all of the code that actually interacts with
-//! libtest, so that it can be easily removed after the new executor becomes
-//! the default.
-
-use std::borrow::Cow;
-use std::io;
-
-use crate::common::Config;
-use crate::executor::{CollectedTest, CollectedTestDesc, ColorConfig, OutputFormat, ShouldPanic};
-
-/// Delegates to libtest to run the list of collected tests.
-///
-/// Returns `Ok(true)` if all tests passed, or `Ok(false)` if one or more tests failed.
-pub(crate) fn execute_tests(config: &Config, tests: Vec<CollectedTest>) -> io::Result<bool> {
-    let opts = test_opts(config);
-    let tests = tests.into_iter().map(|t| t.into_libtest()).collect::<Vec<_>>();
-
-    test::run_tests_console(&opts, tests)
-}
-
-impl CollectedTest {
-    fn into_libtest(self) -> test::TestDescAndFn {
-        let Self { desc, config, testpaths, revision } = self;
-        let CollectedTestDesc { name, ignore, ignore_message, should_panic } = desc;
-
-        // Libtest requires the ignore message to be a &'static str, so we might
-        // have to leak memory to create it. This is fine, as we only do so once
-        // per test, so the leak won't grow indefinitely.
-        let ignore_message = ignore_message.map(|msg| match msg {
-            Cow::Borrowed(s) => s,
-            Cow::Owned(s) => &*String::leak(s),
-        });
-
-        let desc = test::TestDesc {
-            name: test::DynTestName(name),
-            ignore,
-            ignore_message,
-            source_file: "",
-            start_line: 0,
-            start_col: 0,
-            end_line: 0,
-            end_col: 0,
-            should_panic: should_panic.to_libtest(),
-            compile_fail: false,
-            no_run: false,
-            test_type: test::TestType::Unknown,
-        };
-
-        // This closure is invoked when libtest returns control to compiletest
-        // to execute the test.
-        let testfn = test::DynTestFn(Box::new(move || {
-            crate::runtest::run(config, &testpaths, revision.as_deref());
-            Ok(())
-        }));
-
-        test::TestDescAndFn { desc, testfn }
-    }
-}
-
-impl ColorConfig {
-    fn to_libtest(self) -> test::ColorConfig {
-        match self {
-            Self::AutoColor => test::ColorConfig::AutoColor,
-            Self::AlwaysColor => test::ColorConfig::AlwaysColor,
-            Self::NeverColor => test::ColorConfig::NeverColor,
-        }
-    }
-}
-
-impl OutputFormat {
-    fn to_libtest(self) -> test::OutputFormat {
-        match self {
-            Self::Pretty => test::OutputFormat::Pretty,
-            Self::Terse => test::OutputFormat::Terse,
-            Self::Json => test::OutputFormat::Json,
-        }
-    }
-}
-
-impl ShouldPanic {
-    fn to_libtest(self) -> test::ShouldPanic {
-        match self {
-            Self::No => test::ShouldPanic::No,
-            Self::Yes => test::ShouldPanic::Yes,
-        }
-    }
-}
-
-fn test_opts(config: &Config) -> test::TestOpts {
-    test::TestOpts {
-        exclude_should_panic: false,
-        filters: config.filters.clone(),
-        filter_exact: config.filter_exact,
-        run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
-        format: config.format.to_libtest(),
-        logfile: None,
-        run_tests: true,
-        bench_benchmarks: true,
-        nocapture: config.nocapture,
-        color: config.color.to_libtest(),
-        shuffle: false,
-        shuffle_seed: None,
-        test_threads: None,
-        skip: config.skip.clone(),
-        list: false,
-        options: test::Options::new(),
-        time_options: None,
-        force_run_in_process: false,
-        fail_fast: config.fail_fast,
-    }
-}
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 2b203bb309c..8bee9caacc9 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -593,7 +593,7 @@ impl TestProps {
                         config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
                     {
                         self.dont_require_annotations
-                            .insert(ErrorKind::expect_from_user_str(err_kind.trim()));
+                            .insert(ErrorKind::from_user_str(err_kind.trim()));
                     }
                 },
             );
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs
index 62fe538ee32..960f5ba5888 100644
--- a/src/tools/compiletest/src/json.rs
+++ b/src/tools/compiletest/src/json.rs
@@ -229,7 +229,7 @@ fn push_actual_errors(
     // Convert multi-line messages into multiple errors.
     // We expect to replace these with something more structured anyhow.
     let mut message_lines = diagnostic.message.lines();
-    let kind = Some(ErrorKind::from_compiler_str(&diagnostic.level));
+    let kind = ErrorKind::from_compiler_str(&diagnostic.level);
     let first_line = message_lines.next().unwrap_or(&diagnostic.message);
     if primary_spans.is_empty() {
         static RE: OnceLock<Regex> = OnceLock::new();
@@ -278,7 +278,7 @@ fn push_actual_errors(
             for (index, line) in suggested_replacement.lines().enumerate() {
                 errors.push(Error {
                     line_num: Some(span.line_start + index),
-                    kind: Some(ErrorKind::Suggestion),
+                    kind: ErrorKind::Suggestion,
                     msg: line.to_string(),
                     require_annotation: true,
                 });
@@ -297,7 +297,7 @@ fn push_actual_errors(
     for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) {
         errors.push(Error {
             line_num: Some(span.line_start),
-            kind: Some(ErrorKind::Note),
+            kind: ErrorKind::Note,
             msg: span.label.clone().unwrap(),
             require_annotation: true,
         });
@@ -317,7 +317,7 @@ fn push_backtrace(
     if Path::new(&expansion.span.file_name) == Path::new(&file_name) {
         errors.push(Error {
             line_num: Some(expansion.span.line_start),
-            kind: Some(ErrorKind::Note),
+            kind: ErrorKind::Note,
             msg: format!("in this expansion of {}", expansion.macro_decl_name),
             require_annotation: true,
         });
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 788bafaa724..0db4d3f6a41 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -1,11 +1,10 @@
 #![crate_name = "compiletest"]
-// Needed by the libtest-based test executor.
-#![feature(test)]
 // Needed by the "new" test executor that does not depend on libtest.
+// FIXME(Zalathar): We should be able to get rid of `internal_output_capture`,
+// by having `runtest` manually capture all of its println-like output instead.
+// That would result in compiletest being written entirely in stable Rust!
 #![feature(internal_output_capture)]
 
-extern crate test;
-
 #[cfg(test)]
 mod tests;
 
@@ -448,8 +447,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
         diff_command: matches.opt_str("compiletest-diff-tool"),
 
         minicore_path: opt_path(matches, "minicore-path"),
-
-        no_new_executor: matches.opt_present("no-new-executor"),
     }
 }
 
@@ -576,12 +573,10 @@ pub fn run_tests(config: Arc<Config>) {
     // Delegate to the executor to filter and run the big list of test structures
     // created during test discovery. When the executor decides to run a test,
     // it will return control to the rest of compiletest by calling `runtest::run`.
-    let res = if !config.no_new_executor {
-        Ok(executor::run_tests(&config, tests))
-    } else {
-        // FIXME(Zalathar): Eventually remove the libtest executor entirely.
-        crate::executor::libtest::execute_tests(&config, tests)
-    };
+    // FIXME(Zalathar): Once we're confident that we won't need to revert the
+    // removal of the libtest-based executor, remove this Result and other
+    // remnants of the old executor.
+    let res: io::Result<bool> = Ok(executor::run_tests(&config, tests));
 
     // Check the outcome reported by libtest.
     match res {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index fe23cce81e9..97cb82c9e36 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -675,9 +675,7 @@ impl<'test> TestCx<'test> {
             "check_expected_errors: expected_errors={:?} proc_res.status={:?}",
             expected_errors, proc_res.status
         );
-        if proc_res.status.success()
-            && expected_errors.iter().any(|x| x.kind == Some(ErrorKind::Error))
-        {
+        if proc_res.status.success() && expected_errors.iter().any(|x| x.kind == ErrorKind::Error) {
             self.fatal_proc_rec("process did not return an error status", proc_res);
         }
 
@@ -709,7 +707,7 @@ impl<'test> TestCx<'test> {
         // if one of them actually occurs in the test.
         let expected_kinds: HashSet<_> = [ErrorKind::Error, ErrorKind::Warning]
             .into_iter()
-            .chain(expected_errors.iter().filter_map(|e| e.kind))
+            .chain(expected_errors.iter().map(|e| e.kind))
             .collect();
 
         // Parse the JSON output from the compiler and extract out the messages.
@@ -723,8 +721,7 @@ impl<'test> TestCx<'test> {
                 expected_errors.iter().enumerate().position(|(index, expected_error)| {
                     !found[index]
                         && actual_error.line_num == expected_error.line_num
-                        && (expected_error.kind.is_none()
-                            || actual_error.kind == expected_error.kind)
+                        && actual_error.kind == expected_error.kind
                         && actual_error.msg.contains(&expected_error.msg)
                 });
 
@@ -737,19 +734,14 @@ impl<'test> TestCx<'test> {
 
                 None => {
                     if actual_error.require_annotation
-                        && actual_error.kind.map_or(false, |kind| {
-                            expected_kinds.contains(&kind)
-                                && !self.props.dont_require_annotations.contains(&kind)
-                        })
+                        && expected_kinds.contains(&actual_error.kind)
+                        && !self.props.dont_require_annotations.contains(&actual_error.kind)
                     {
                         self.error(&format!(
                             "{}:{}: unexpected {}: '{}'",
                             file_name,
                             actual_error.line_num_str(),
-                            actual_error
-                                .kind
-                                .as_ref()
-                                .map_or(String::from("message"), |k| k.to_string()),
+                            actual_error.kind,
                             actual_error.msg
                         ));
                         unexpected.push(actual_error);
@@ -766,7 +758,7 @@ impl<'test> TestCx<'test> {
                     "{}:{}: expected {} not found: {}",
                     file_name,
                     expected_error.line_num_str(),
-                    expected_error.kind.as_ref().map_or("message".into(), |k| k.to_string()),
+                    expected_error.kind,
                     expected_error.msg
                 ));
                 not_found.push(expected_error);
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
index e87b037cd28..cf0ae14f81b 100644
--- a/src/tools/compiletest/src/runtest/ui.rs
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -6,8 +6,8 @@ use rustfix::{Filter, apply_suggestions, get_suggestions_from_json};
 use tracing::debug;
 
 use super::{
-    AllowUnused, Emit, ErrorKind, FailMode, LinkToAux, PassMode, TargetLocation, TestCx,
-    TestOutput, Truncated, UI_FIXED, WillExecute,
+    AllowUnused, Emit, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, TestOutput,
+    Truncated, UI_FIXED, WillExecute,
 };
 use crate::{errors, json};
 
@@ -176,7 +176,7 @@ impl TestCx<'_> {
             let msg = format!(
                 "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
                 expected_errors[0].line_num_str(),
-                expected_errors[0].kind.unwrap_or(ErrorKind::Error),
+                expected_errors[0].kind,
             );
             self.fatal(&msg);
         }
diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml
index 59bae513a58..9dbf51e9796 100644
--- a/src/tools/miri/.github/workflows/ci.yml
+++ b/src/tools/miri/.github/workflows/ci.yml
@@ -89,41 +89,16 @@ jobs:
             # Check if all jobs that we depend on (in the needs array) were successful.
             jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
 
-  cron-fail-notify:
-    name: cronjob failure notification
+  cron-rustc-pull:
+    name: automatic pull from rustc
     runs-on: ubuntu-latest
     permissions:
         # The cronjob needs to be able to push to the repo...
         contents: write
         # ... and create a PR.
         pull-requests: write
-    needs: [build, style, coverage]
-    if: ${{ github.event_name == 'schedule' && failure() }}
+    if: ${{ github.event_name == 'schedule' }}
     steps:
-      # Send a Zulip notification
-      - name: Install zulip-send
-        run: pip3 install zulip
-      - name: Send Zulip notification
-        env:
-          ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
-          ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
-        run: |
-          ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
-            --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \
-            --message 'Dear @*T-miri*,
-
-          It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
-
-          This likely means that rustc changed the miri directory and
-          we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo).
-
-          Would you mind investigating this issue?
-
-          Thanks in advance!
-          Sincerely,
-          The Miri Cronjobs Bot'
-
-      # Attempt to auto-sync with rustc
       - uses: actions/checkout@v4
         with:
           fetch-depth: 256 # get a bit more of the history
@@ -143,18 +118,45 @@ jobs:
         run: |
           ./miri toolchain
           ./miri fmt --check || (./miri fmt && git commit -am "fmt")
-      - name: Push changes to a branch
+      - name: Push changes to a branch and create PR
         run: |
+          # `git diff --exit-code` "succeeds" if the diff is empty.
+          if git diff --exit-code HEAD^; then echo "Nothing changed in rustc, skipping PR"; exit 0; fi
+          # The diff is non-empty, create a PR.
           BRANCH="rustup-$(date -u +%Y-%m-%d)"
           git switch -c $BRANCH
           git push -u origin $BRANCH
-      - name: Create Pull Request
-        run: |
-          PR=$(gh pr create -B master --title 'Automatic Rustup' --body 'Please close and re-open this PR to trigger CI, then enable auto-merge.')
-          ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
-            --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \
-            --message "A PR doing a rustc-pull [has been automatically created]($PR) for your convenience."
+          gh pr create -B master --title 'Automatic Rustup' --body 'Please close and re-open this PR to trigger CI, then enable auto-merge.'
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
           ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
+
+  cron-fail-notify:
+    name: cronjob failure notification
+    runs-on: ubuntu-latest
+    needs: [build, style, coverage]
+    if: ${{ github.event_name == 'schedule' && failure() }}
+    steps:
+      # Send a Zulip notification
+      - name: Install zulip-send
+        run: pip3 install zulip
+      - name: Send Zulip notification
+        env:
+          ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
+          ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
+        run: |
+          ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
+            --stream miri --subject "Miri Build Failure ($(date -u +%Y-%m))" \
+            --message 'Dear @*T-miri*,
+
+          It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
+
+          This likely means that rustc changed the miri directory and
+          we now need to do a [`./miri rustc-pull`](https://github.com/rust-lang/miri/blob/master/CONTRIBUTING.md#importing-changes-from-the-rustc-repo).
+
+          Would you mind investigating this issue?
+
+          Thanks in advance!
+          Sincerely,
+          The Miri Cronjobs Bot'
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index e8ea988558c..95e1770aa7b 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -489,7 +489,7 @@ Miri knows where it is supposed to start execution:
 
 ```rust
 #[cfg(miri)]
-#[no_mangle]
+#[unsafe(no_mangle)]
 fn miri_start(argc: isize, argv: *const *const u8) -> isize {
     // Call the actual start function that your project implements, based on your target's conventions.
 }
diff --git a/src/tools/miri/bench-cargo-miri/mse/src/main.rs b/src/tools/miri/bench-cargo-miri/mse/src/main.rs
index 06d5487d1d4..69c7c39cdd7 100644
--- a/src/tools/miri/bench-cargo-miri/mse/src/main.rs
+++ b/src/tools/miri/bench-cargo-miri/mse/src/main.rs
@@ -13,7 +13,7 @@ fn read_i16(buffer: &[u8], index: usize) -> i16 {
     const SIZE: usize = size_of::<i16>();
     let mut bytes: [u8; SIZE] = [0u8; SIZE];
     bytes.copy_from_slice(&buffer[(index * SIZE)..(index * SIZE + SIZE)]);
-    unsafe { std::mem::transmute(bytes) }
+    i16::from_ne_bytes(bytes)
 }
 
 fn mse(samples: usize, frame_buf: &[i16], buf_ref: &[u8]) -> f64 {
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index d1107e51509..59d53891217 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-1bc56185ee257ed829a0aea7abdc3b03c5fed887
+1b8ab72680f36e783af84c1a3c4f8508572bd9f9
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index c263e86c082..335e8d76999 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -107,47 +107,6 @@ fn align_addr(addr: u64, align: u64) -> u64 {
 
 impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
 trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    // Returns the exposed `AllocId` that corresponds to the specified addr,
-    // or `None` if the addr is out of bounds
-    fn alloc_id_from_addr(&self, addr: u64, size: i64) -> Option<AllocId> {
-        let this = self.eval_context_ref();
-        let global_state = this.machine.alloc_addresses.borrow();
-        assert!(global_state.provenance_mode != ProvenanceMode::Strict);
-
-        // We always search the allocation to the right of this address. So if the size is structly
-        // negative, we have to search for `addr-1` instead.
-        let addr = if size >= 0 { addr } else { addr.saturating_sub(1) };
-        let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr);
-
-        // Determine the in-bounds provenance for this pointer.
-        let alloc_id = match pos {
-            Ok(pos) => Some(global_state.int_to_ptr_map[pos].1),
-            Err(0) => None,
-            Err(pos) => {
-                // This is the largest of the addresses smaller than `int`,
-                // i.e. the greatest lower bound (glb)
-                let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1];
-                // This never overflows because `addr >= glb`
-                let offset = addr - glb;
-                // We require this to be strict in-bounds of the allocation. This arm is only
-                // entered for addresses that are not the base address, so even zero-sized
-                // allocations will get recognized at their base address -- but all other
-                // allocations will *not* be recognized at their "end" address.
-                let size = this.get_alloc_info(alloc_id).size;
-                if offset < size.bytes() { Some(alloc_id) } else { None }
-            }
-        }?;
-
-        // We only use this provenance if it has been exposed.
-        if global_state.exposed.contains(&alloc_id) {
-            // This must still be live, since we remove allocations from `int_to_ptr_map` when they get freed.
-            debug_assert!(this.is_alloc_live(alloc_id));
-            Some(alloc_id)
-        } else {
-            None
-        }
-    }
-
     fn addr_from_alloc_id_uncached(
         &self,
         global_state: &mut GlobalStateInner,
@@ -242,11 +201,65 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             interp_ok(base_addr)
         }
     }
+}
 
+impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
+pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
+    // Returns the `AllocId` that corresponds to the specified addr,
+    // or `None` if the addr is out of bounds.
+    // Setting `only_exposed_allocations` selects whether only exposed allocations are considered.
+    fn alloc_id_from_addr(
+        &self,
+        addr: u64,
+        size: i64,
+        only_exposed_allocations: bool,
+    ) -> Option<AllocId> {
+        let this = self.eval_context_ref();
+        let global_state = this.machine.alloc_addresses.borrow();
+        assert!(global_state.provenance_mode != ProvenanceMode::Strict);
+
+        // We always search the allocation to the right of this address. So if the size is strictly
+        // negative, we have to search for `addr-1` instead.
+        let addr = if size >= 0 { addr } else { addr.saturating_sub(1) };
+        let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr);
+
+        // Determine the in-bounds provenance for this pointer.
+        let alloc_id = match pos {
+            Ok(pos) => Some(global_state.int_to_ptr_map[pos].1),
+            Err(0) => None,
+            Err(pos) => {
+                // This is the largest of the addresses smaller than `int`,
+                // i.e. the greatest lower bound (glb)
+                let (glb, alloc_id) = global_state.int_to_ptr_map[pos - 1];
+                // This never overflows because `addr >= glb`
+                let offset = addr - glb;
+                // We require this to be strict in-bounds of the allocation. This arm is only
+                // entered for addresses that are not the base address, so even zero-sized
+                // allocations will get recognized at their base address -- but all other
+                // allocations will *not* be recognized at their "end" address.
+                let size = this.get_alloc_info(alloc_id).size;
+                if offset < size.bytes() { Some(alloc_id) } else { None }
+            }
+        }?;
+
+        // We only use this provenance if it has been exposed, or if the caller requested also non-exposed allocations
+        if !only_exposed_allocations || global_state.exposed.contains(&alloc_id) {
+            // This must still be live, since we remove allocations from `int_to_ptr_map` when they get freed.
+            debug_assert!(this.is_alloc_live(alloc_id));
+            Some(alloc_id)
+        } else {
+            None
+        }
+    }
+
+    /// Returns the base address of an allocation, or an error if no base address could be found
+    ///
+    /// # Panics
+    /// If `memory_kind = None` and the `alloc_id` is not cached, meaning that the first call to this function per `alloc_id` must get the `memory_kind`.
     fn addr_from_alloc_id(
         &self,
         alloc_id: AllocId,
-        memory_kind: MemoryKind,
+        memory_kind: Option<MemoryKind>,
     ) -> InterpResult<'tcx, u64> {
         let this = self.eval_context_ref();
         let mut global_state = this.machine.alloc_addresses.borrow_mut();
@@ -256,8 +269,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             Some(&addr) => interp_ok(addr),
             None => {
                 // First time we're looking for the absolute address of this allocation.
+                let memory_kind =
+                    memory_kind.expect("memory_kind is required since alloc_id is not cached");
                 let base_addr =
-                    self.addr_from_alloc_id_uncached(global_state, alloc_id, memory_kind)?;
+                    this.addr_from_alloc_id_uncached(global_state, alloc_id, memory_kind)?;
                 trace!("Assigning base address {:#x} to allocation {:?}", base_addr, alloc_id);
 
                 // Store address in cache.
@@ -283,10 +298,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
         }
     }
-}
 
-impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
-pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn expose_provenance(&self, provenance: Provenance) -> InterpResult<'tcx> {
         let this = self.eval_context_ref();
         let mut global_state = this.machine.alloc_addresses.borrow_mut();
@@ -365,7 +377,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let alloc_id = prov.alloc_id();
 
         // Get a pointer to the beginning of this allocation.
-        let base_addr = this.addr_from_alloc_id(alloc_id, kind)?;
+        let base_addr = this.addr_from_alloc_id(alloc_id, Some(kind))?;
         let base_ptr = interpret::Pointer::new(
             Provenance::Concrete { alloc_id, tag },
             Size::from_bytes(base_addr),
@@ -388,7 +400,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`.
             // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case
             // this function gets called before the first time `addr_from_alloc_id` gets called.
-            this.addr_from_alloc_id(id, MiriMemoryKind::Global.into())?;
+            this.addr_from_alloc_id(id, Some(MiriMemoryKind::Global.into()))?;
             // The memory we need here will have already been allocated during an earlier call to
             // `addr_from_alloc_id` for this allocation. So don't create a new `MiriAllocBytes` here, instead
             // fetch the previously prepared bytes from `prepared_alloc_bytes`.
@@ -423,7 +435,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             alloc_id
         } else {
             // A wildcard pointer.
-            this.alloc_id_from_addr(addr.bytes(), size)?
+            let only_exposed_allocations = true;
+            this.alloc_id_from_addr(addr.bytes(), size, only_exposed_allocations)?
         };
 
         // This cannot fail: since we already have a pointer with that provenance, adjust_alloc_root_pointer
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 4e8fe0ca8ad..8ff1c9d6ff0 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -106,7 +106,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
         } else {
             tcx.dcx().fatal(
                 "`miri_start` must have the following signature:\n\
-                        fn miri_start(argc: isize, argv: *const *const u8) -> isize",
+                fn miri_start(argc: isize, argv: *const *const u8) -> isize",
             );
         }
     } else {
@@ -115,7 +115,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
             Alternatively, you can export a `miri_start` function:\n\
             \n\
             #[cfg(miri)]\n\
-            #[no_mangle]\n\
+            #[unsafe(no_mangle)]\n\
             fn miri_start(argc: isize, argv: *const *const u8) -> isize {\
             \n    // Call the actual start function that your project implements, based on your target's conventions.\n\
             }"
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
index a429940748c..dbfa9807e3b 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
@@ -61,8 +61,7 @@ fn all_read_accesses_commute() {
                 // ... and produce the same final result.
                 assert_eq!(
                     loc12, loc21,
-                    "Read accesses {:?} followed by {:?} do not commute !",
-                    rel1, rel2
+                    "Read accesses {rel1:?} followed by {rel2:?} do not commute !"
                 );
             }
         }
@@ -674,8 +673,8 @@ mod spurious_read {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
             let (x, y) = self.retag_permissions();
             write!(f, "{}; ", self.xy_rel)?;
-            write!(f, "y: ({}); ", y,)?;
-            write!(f, "retag x ({}); ", x)?;
+            write!(f, "y: ({y}); ")?;
+            write!(f, "retag x ({x}); ")?;
 
             write!(f, "<arbitrary code>; <spurious read x>;")?;
             Ok(())
@@ -730,17 +729,17 @@ mod spurious_read {
                         // protector.
                         final_source
                             .distinguishable::</*X*/ AllowRet, /*Y*/ AllowRet>(&final_target)
-                            .then_some(format!("{}", final_target))
+                            .then_some(format!("{final_target}"))
                     } else {
                         Some(format!("UB"))
                     }
                 };
                 if let Some(final_target) = distinguishable {
                     eprintln!(
-                        "For pattern '{}', inserting a spurious read through x makes the final state '{}' instead of '{}' which is observable",
-                        pat, final_target, final_source
+                        "For pattern '{pat}', inserting a spurious read through x makes the final state '{final_target}' \
+                        instead of '{final_source}' which is observable"
                     );
-                    eprintln!("  (arbitrary code instanciated with '{}')", opaque);
+                    eprintln!("  (arbitrary code instanciated with '{opaque}')");
                     err += 1;
                     // We found an instanciation of the opaque code that makes this Pattern
                     // fail, we don't really need to check the rest.
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 923031dbbd1..847c6823475 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -381,7 +381,7 @@ impl AccessType {
         });
 
         if let Some(ty) = ty {
-            msg.push_str(&format!(" of type `{}`", ty));
+            msg.push_str(&format!(" of type `{ty}`"));
         }
 
         msg
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 1af3d1abc64..a3aa8bbbfb3 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1017,7 +1017,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     }
 
     /// Check that the given `caller_fn_abi` matches the expected ABI described by
-    /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and the return the list of
+    /// `callee_abi`, `callee_input_tys`, `callee_output_ty`, and then returns the list of
     /// arguments.
     fn check_shim_abi<'a, const N: usize>(
         &mut self,
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 7d60a7e5c48..3334c0b5edf 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -7,13 +7,13 @@ use rand::Rng;
 use rustc_abi::Size;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::mir;
-use rustc_middle::ty::{self, FloatTy, ScalarInt};
+use rustc_middle::ty::{self, FloatTy};
 use rustc_span::{Symbol, sym};
 
 use self::atomic::EvalContextExt as _;
 use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count};
 use self::simd::EvalContextExt as _;
-use crate::math::apply_random_float_error_ulp;
+use crate::math::apply_random_float_error_to_imm;
 use crate::*;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -473,26 +473,3 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(EmulateItemResult::NeedsReturn)
     }
 }
-
-/// Applies a random 16ULP floating point error to `val` and returns the new value.
-/// Will fail if `val` is not a floating point number.
-fn apply_random_float_error_to_imm<'tcx>(
-    ecx: &mut MiriInterpCx<'tcx>,
-    val: ImmTy<'tcx>,
-    ulp_exponent: u32,
-) -> InterpResult<'tcx, ImmTy<'tcx>> {
-    let scalar = val.to_scalar_int()?;
-    let res: ScalarInt = match val.layout.ty.kind() {
-        ty::Float(FloatTy::F16) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(),
-        ty::Float(FloatTy::F32) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(),
-        ty::Float(FloatTy::F64) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(),
-        ty::Float(FloatTy::F128) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(),
-        _ => bug!("intrinsic called with non-float input type"),
-    };
-
-    interp_ok(ImmTy::from_scalar_int(res, val.layout))
-}
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index ea59d327be8..55aa3d6fa68 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -721,9 +721,8 @@ impl<'tcx> MiriMachine<'tcx> {
                 // Check if host target == the session target.
                 if host_triple != target_triple {
                     panic!(
-                        "calling external C functions in linked .so file requires host and target to be the same: host={}, target={}",
-                        host_triple,
-                        target_triple,
+                        "calling native C functions in linked .so file requires host and target to be the same: \
+                        host={host_triple}, target={target_triple}",
                     );
                 }
                 // Note: it is the user's responsibility to provide a correct SO file.
@@ -1200,6 +1199,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     }
 
     #[inline(always)]
+    fn apply_float_nondet(
+        ecx: &mut InterpCx<'tcx, Self>,
+        val: ImmTy<'tcx>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx>> {
+        crate::math::apply_random_float_error_to_imm(
+            ecx, val, 2 /* log2(4) */
+        )
+    }
+
+    #[inline(always)]
     fn equal_float_min_max<F: Float>(ecx: &MiriInterpCx<'tcx>, a: F, b: F) -> F {
         ecx.equal_float_min_max(a, b)
     }
diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs
index fdd021f8539..2ff29c7ac1a 100644
--- a/src/tools/miri/src/math.rs
+++ b/src/tools/miri/src/math.rs
@@ -1,6 +1,9 @@
 use rand::Rng as _;
 use rustc_apfloat::Float as _;
 use rustc_apfloat::ieee::IeeeFloat;
+use rustc_middle::ty::{self, FloatTy, ScalarInt};
+
+use crate::*;
 
 /// Disturbes a floating-point result by a relative error in the range (-2^scale, 2^scale).
 ///
@@ -43,6 +46,29 @@ pub(crate) fn apply_random_float_error_ulp<F: rustc_apfloat::Float>(
     apply_random_float_error(ecx, val, err_scale)
 }
 
+/// Applies a random 16ULP floating point error to `val` and returns the new value.
+/// Will fail if `val` is not a floating point number.
+pub(crate) fn apply_random_float_error_to_imm<'tcx>(
+    ecx: &mut MiriInterpCx<'tcx>,
+    val: ImmTy<'tcx>,
+    ulp_exponent: u32,
+) -> InterpResult<'tcx, ImmTy<'tcx>> {
+    let scalar = val.to_scalar_int()?;
+    let res: ScalarInt = match val.layout.ty.kind() {
+        ty::Float(FloatTy::F16) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(),
+        ty::Float(FloatTy::F32) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(),
+        ty::Float(FloatTy::F64) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(),
+        ty::Float(FloatTy::F128) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(),
+        _ => bug!("intrinsic called with non-float input type"),
+    };
+
+    interp_ok(ImmTy::from_scalar_int(res, val.layout))
+}
+
 pub(crate) fn sqrt<S: rustc_apfloat::ieee::Semantics>(x: IeeeFloat<S>) -> IeeeFloat<S> {
     match x.category() {
         // preserve zero sign
diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs
index fb80a36af9f..28f4ca5bb1b 100644
--- a/src/tools/miri/src/shims/time.rs
+++ b/src/tools/miri/src/shims/time.rs
@@ -21,7 +21,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &mut self,
         clk_id_op: &OpTy<'tcx>,
         tp_op: &OpTy<'tcx>,
-    ) -> InterpResult<'tcx, Scalar> {
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         // This clock support is deliberately minimal because a lot of clock types have fiddly
         // properties (is it possible for Miri to be suspended independently of the host?). If you
         // have a use for another clock type, please open an issue.
@@ -29,8 +30,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let this = self.eval_context_mut();
 
         this.assert_target_os_is_unix("clock_gettime");
+        let clockid_t_size = this.libc_ty_layout("clockid_t").size;
 
-        let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
+        let clk_id = this.read_scalar(clk_id_op)?.to_int(clockid_t_size)?;
         let tp = this.deref_pointer_as(tp_op, this.libc_ty_layout("timespec"))?;
 
         let absolute_clocks;
@@ -43,34 +45,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
                 // is just specified to be "faster and less precise", so we implement both the same way.
                 absolute_clocks = vec![
-                    this.eval_libc_i32("CLOCK_REALTIME"),
-                    this.eval_libc_i32("CLOCK_REALTIME_COARSE"),
+                    this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?,
+                    this.eval_libc("CLOCK_REALTIME_COARSE").to_int(clockid_t_size)?,
                 ];
                 // The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
                 // never allowed to go backwards. We don't need to do any additional monotonicity
                 // enforcement because std::time::Instant already guarantees that it is monotonic.
                 relative_clocks = vec![
-                    this.eval_libc_i32("CLOCK_MONOTONIC"),
-                    this.eval_libc_i32("CLOCK_MONOTONIC_COARSE"),
+                    this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?,
+                    this.eval_libc("CLOCK_MONOTONIC_COARSE").to_int(clockid_t_size)?,
                 ];
             }
             "macos" => {
-                absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")];
-                relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")];
+                absolute_clocks = vec![this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?];
+                relative_clocks = vec![this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?];
                 // `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
                 // that's not really something a program running inside Miri can tell, anyway.
                 // We need to support it because std uses it.
-                relative_clocks.push(this.eval_libc_i32("CLOCK_UPTIME_RAW"));
+                relative_clocks.push(this.eval_libc("CLOCK_UPTIME_RAW").to_int(clockid_t_size)?);
             }
             "solaris" | "illumos" => {
                 // The REALTIME clock returns the actual time since the Unix epoch.
-                absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")];
+                absolute_clocks = vec![this.eval_libc("CLOCK_REALTIME").to_int(clockid_t_size)?];
                 // MONOTONIC, in the other hand, is the high resolution, non-adjustable
                 // clock from an arbitrary time in the past.
                 // Note that the man page mentions HIGHRES but it is just
                 // an alias of MONOTONIC and the libc crate does not expose it anyway.
                 // https://docs.oracle.com/cd/E23824_01/html/821-1465/clock-gettime-3c.html
-                relative_clocks = vec![this.eval_libc_i32("CLOCK_MONOTONIC")];
+                relative_clocks = vec![this.eval_libc("CLOCK_MONOTONIC").to_int(clockid_t_size)?];
             }
             target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
         }
@@ -81,15 +83,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         } else if relative_clocks.contains(&clk_id) {
             this.machine.monotonic_clock.now().duration_since(this.machine.monotonic_clock.epoch())
         } else {
-            return this.set_last_error_and_return_i32(LibcError("EINVAL"));
+            return this.set_last_error_and_return(LibcError("EINVAL"), dest);
         };
 
         let tv_sec = duration.as_secs();
         let tv_nsec = duration.subsec_nanos();
 
         this.write_int_fields(&[tv_sec.into(), tv_nsec.into()], &tp)?;
+        this.write_int(0, dest)?;
 
-        interp_ok(Scalar::from_i32(0))
+        interp_ok(())
     }
 
     fn gettimeofday(
@@ -188,10 +191,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 tm_zone.push('+');
             }
             let offset_hour = offset_in_seconds.abs() / 3600;
-            write!(tm_zone, "{:02}", offset_hour).unwrap();
+            write!(tm_zone, "{offset_hour:02}").unwrap();
             let offset_min = (offset_in_seconds.abs() % 3600) / 60;
             if offset_min != 0 {
-                write!(tm_zone, "{:02}", offset_min).unwrap();
+                write!(tm_zone, "{offset_min:02}").unwrap();
             }
 
             // Add null terminator for C string compatibility.
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 5e6259c3574..026aa1f9503 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -112,51 +112,122 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // Environment related shims
             "getenv" => {
-                let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [name] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.machine.layouts.mut_raw_ptr.ty,
+                    args,
+                )?;
                 let result = this.getenv(name)?;
                 this.write_pointer(result, dest)?;
             }
             "unsetenv" => {
-                let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [name] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.unsetenv(name)?;
                 this.write_scalar(result, dest)?;
             }
             "setenv" => {
-                let [name, value, overwrite] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [name, value, overwrite] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.tcx.types.i32,
+                    ],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 this.read_scalar(overwrite)?.to_i32()?;
                 let result = this.setenv(name, value)?;
                 this.write_scalar(result, dest)?;
             }
             "getcwd" => {
-                let [buf, size] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [buf, size] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.usize],
+                    this.machine.layouts.mut_raw_ptr.ty,
+                    args,
+                )?;
                 let result = this.getcwd(buf, size)?;
                 this.write_pointer(result, dest)?;
             }
             "chdir" => {
-                let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [path] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.chdir(path)?;
                 this.write_scalar(result, dest)?;
             }
             "getpid" => {
-                let [] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [],
+                    this.libc_ty_layout("pid_t").ty,
+                    args,
+                )?;
                 let result = this.getpid()?;
                 this.write_scalar(result, dest)?;
             }
             "sysconf" => {
-                let [val] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [val] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let result = this.sysconf(val)?;
                 this.write_scalar(result, dest)?;
             }
             // File descriptors
             "read" => {
-                let [fd, buf, count] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd, buf, count] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.usize],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
                 this.read(fd, buf, count, None, dest)?;
             }
             "write" => {
-                let [fd, buf, n] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd, buf, n] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.tcx.types.usize,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
@@ -164,38 +235,88 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, None, dest)?;
             }
             "pread" => {
-                let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off_t = this.libc_ty_layout("off_t");
+                let [fd, buf, count, offset] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.machine.layouts.mut_raw_ptr.ty,
+                        this.tcx.types.usize,
+                        off_t.ty,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
-                let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
+                let offset = this.read_scalar(offset)?.to_int(off_t.size)?;
                 this.read(fd, buf, count, Some(offset), dest)?;
             }
             "pwrite" => {
-                let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off_t = this.libc_ty_layout("off_t");
+                let [fd, buf, n, offset] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.tcx.types.usize,
+                        off_t.ty,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
-                let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
+                let offset = this.read_scalar(offset)?.to_int(off_t.size)?;
                 trace!("Called pwrite({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset);
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
             "pread64" => {
-                let [fd, buf, count, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off64_t = this.libc_ty_layout("off64_t");
+                let [fd, buf, count, offset] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.machine.layouts.mut_raw_ptr.ty,
+                        this.tcx.types.usize,
+                        off64_t.ty,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
-                let offset =
-                    this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
+                let offset = this.read_scalar(offset)?.to_int(off64_t.size)?;
                 this.read(fd, buf, count, Some(offset), dest)?;
             }
             "pwrite64" => {
-                let [fd, buf, n, offset] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off64_t = this.libc_ty_layout("off64_t");
+                let [fd, buf, n, offset] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.tcx.types.usize,
+                        off64_t.ty,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
-                let offset =
-                    this.read_scalar(offset)?.to_int(this.libc_ty_layout("off64_t").size)?;
+                let offset = this.read_scalar(offset)?.to_int(off64_t.size)?;
                 trace!("Called pwrite64({:?}, {:?}, {:?}, {:?})", fd, buf, count, offset);
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
@@ -218,13 +339,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
             "dup" => {
-                let [old_fd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [old_fd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let old_fd = this.read_scalar(old_fd)?.to_i32()?;
                 let new_fd = this.dup(old_fd)?;
                 this.write_scalar(new_fd, dest)?;
             }
             "dup2" => {
-                let [old_fd, new_fd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [old_fd, new_fd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let old_fd = this.read_scalar(old_fd)?.to_i32()?;
                 let new_fd = this.read_scalar(new_fd)?.to_i32()?;
                 let result = this.dup2(old_fd, new_fd)?;
@@ -233,7 +368,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "flock" => {
                 // Currently this function does not exist on all Unixes, e.g. on Solaris.
                 this.check_target_os(&["linux", "freebsd", "macos", "illumos"], link_name)?;
-                let [fd, op] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd, op] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let op = this.read_scalar(op)?.to_i32()?;
                 let result = this.flock(fd, op)?;
@@ -250,140 +392,311 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
             "unlink" => {
-                let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [path] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.unlink(path)?;
                 this.write_scalar(result, dest)?;
             }
             "symlink" => {
-                let [target, linkpath] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [target, linkpath] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.symlink(target, linkpath)?;
                 this.write_scalar(result, dest)?;
             }
             "rename" => {
-                let [oldpath, newpath] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [oldpath, newpath] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.rename(oldpath, newpath)?;
                 this.write_scalar(result, dest)?;
             }
             "mkdir" => {
-                let [path, mode] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [path, mode] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty, this.libc_ty_layout("mode_t").ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.mkdir(path, mode)?;
                 this.write_scalar(result, dest)?;
             }
             "rmdir" => {
-                let [path] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [path] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.rmdir(path)?;
                 this.write_scalar(result, dest)?;
             }
             "opendir" => {
-                let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [name] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty],
+                    this.machine.layouts.mut_raw_ptr.ty,
+                    args,
+                )?;
                 let result = this.opendir(name)?;
                 this.write_scalar(result, dest)?;
             }
             "closedir" => {
-                let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [dirp] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.closedir(dirp)?;
                 this.write_scalar(result, dest)?;
             }
             "lseek64" => {
-                let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off64_t = this.libc_ty_layout("off64_t");
+                let [fd, offset, whence] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, off64_t.ty, this.tcx.types.i32],
+                    off64_t.ty,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
-                let offset = this.read_scalar(offset)?.to_i64()?;
+                let offset = this.read_scalar(offset)?.to_int(off64_t.size)?;
                 let whence = this.read_scalar(whence)?.to_i32()?;
-                let result = this.lseek64(fd, offset.into(), whence)?;
-                this.write_scalar(result, dest)?;
+                this.lseek64(fd, offset, whence, dest)?;
             }
             "lseek" => {
-                let [fd, offset, whence] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off_t = this.libc_ty_layout("off_t");
+                let [fd, offset, whence] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, off_t.ty, this.tcx.types.i32],
+                    off_t.ty,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
-                let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
+                let offset = this.read_scalar(offset)?.to_int(off_t.size)?;
                 let whence = this.read_scalar(whence)?.to_i32()?;
-                let result = this.lseek64(fd, offset, whence)?;
-                this.write_scalar(result, dest)?;
+                this.lseek64(fd, offset, whence, dest)?;
             }
             "ftruncate64" => {
-                let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off64_t = this.libc_ty_layout("off64_t");
+                let [fd, length] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, off64_t.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
-                let length = this.read_scalar(length)?.to_i64()?;
-                let result = this.ftruncate64(fd, length.into())?;
+                let length = this.read_scalar(length)?.to_int(off64_t.size)?;
+                let result = this.ftruncate64(fd, length)?;
                 this.write_scalar(result, dest)?;
             }
             "ftruncate" => {
-                let [fd, length] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off_t = this.libc_ty_layout("off_t");
+                let [fd, length] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, off_t.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
-                let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?;
+                let length = this.read_scalar(length)?.to_int(off_t.size)?;
                 let result = this.ftruncate64(fd, length)?;
                 this.write_scalar(result, dest)?;
             }
             "fsync" => {
-                let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.fsync(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "fdatasync" => {
-                let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [fd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.fdatasync(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "readlink" => {
-                let [pathname, buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [pathname, buf, bufsize] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.machine.layouts.const_raw_ptr.ty,
+                        this.machine.layouts.mut_raw_ptr.ty,
+                        this.tcx.types.usize,
+                    ],
+                    this.tcx.types.isize,
+                    args,
+                )?;
                 let result = this.readlink(pathname, buf, bufsize)?;
                 this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
             }
             "posix_fadvise" => {
-                let [fd, offset, len, advice] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let off_t = this.libc_ty_layout("off_t");
+                let [fd, offset, len, advice] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.tcx.types.i32, off_t.ty, off_t.ty, this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 this.read_scalar(fd)?.to_i32()?;
-                this.read_target_isize(offset)?;
-                this.read_target_isize(len)?;
+                this.read_scalar(offset)?.to_int(off_t.size)?;
+                this.read_scalar(len)?.to_int(off_t.size)?;
                 this.read_scalar(advice)?.to_i32()?;
                 // fadvise is only informational, we can ignore it.
                 this.write_null(dest)?;
             }
             "realpath" => {
-                let [path, resolved_path] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [path, resolved_path] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty],
+                    this.machine.layouts.mut_raw_ptr.ty,
+                    args,
+                )?;
                 let result = this.realpath(path, resolved_path)?;
                 this.write_scalar(result, dest)?;
             }
             "mkstemp" => {
-                let [template] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [template] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.mkstemp(template)?;
                 this.write_scalar(result, dest)?;
             }
 
             // Unnamed sockets and pipes
             "socketpair" => {
-                let [domain, type_, protocol, sv] =
-                    this.check_shim(abi, Conv::C, link_name, args)?;
+                let [domain, type_, protocol, sv] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [
+                        this.tcx.types.i32,
+                        this.tcx.types.i32,
+                        this.tcx.types.i32,
+                        this.machine.layouts.mut_raw_ptr.ty,
+                    ],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.socketpair(domain, type_, protocol, sv)?;
                 this.write_scalar(result, dest)?;
             }
             "pipe" => {
-                let [pipefd] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [pipefd] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.pipe2(pipefd, /*flags*/ None)?;
                 this.write_scalar(result, dest)?;
             }
             "pipe2" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
                 this.check_target_os(&["linux", "freebsd", "solaris", "illumos"], link_name)?;
-                let [pipefd, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [pipefd, flags] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty, this.tcx.types.i32],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.pipe2(pipefd, Some(flags))?;
                 this.write_scalar(result, dest)?;
             }
 
             // Time
             "gettimeofday" => {
-                let [tv, tz] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [tv, tz] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.mut_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
                 let result = this.gettimeofday(tv, tz)?;
                 this.write_scalar(result, dest)?;
             }
             "localtime_r" => {
-                let [timep, result_op] = this.check_shim(abi, Conv::C, link_name, args)?;
+                let [timep, result_op] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.machine.layouts.const_raw_ptr.ty, this.machine.layouts.mut_raw_ptr.ty],
+                    this.machine.layouts.mut_raw_ptr.ty,
+                    args,
+                )?;
                 let result = this.localtime_r(timep, result_op)?;
                 this.write_pointer(result, dest)?;
             }
             "clock_gettime" => {
-                let [clk_id, tp] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let result = this.clock_gettime(clk_id, tp)?;
-                this.write_scalar(result, dest)?;
+                let [clk_id, tp] = this.check_shim_abi(
+                    link_name,
+                    abi,
+                    ExternAbi::C { unwind: false },
+                    [this.libc_ty_layout("clockid_t").ty, this.machine.layouts.mut_raw_ptr.ty],
+                    this.tcx.types.i32,
+                    args,
+                )?;
+                this.clock_gettime(clk_id, tp, dest)?;
             }
 
             // Allocation
@@ -834,7 +1147,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // These shims are enabled only when the caller is in the standard library.
             "pthread_attr_getguardsize" if this.frame_in_std() => {
                 let [_attr, guard_size] = this.check_shim(abi, Conv::C, link_name, args)?;
-                let guard_size_layout = this.libc_ty_layout("size_t");
+                let guard_size_layout = this.machine.layouts.usize;
                 let guard_size = this.deref_pointer_as(guard_size, guard_size_layout)?;
                 this.write_scalar(
                     Scalar::from_uint(this.machine.page_size, guard_size_layout.size),
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index fc0f57694a7..1f6acff0787 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -502,7 +502,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(Scalar::from_i32(this.try_unwrap_io_result(fd)?))
     }
 
-    fn lseek64(&mut self, fd_num: i32, offset: i128, whence: i32) -> InterpResult<'tcx, Scalar> {
+    fn lseek64(
+        &mut self,
+        fd_num: i32,
+        offset: i128,
+        whence: i32,
+        dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         // Isolation check is done via `FileDescription` trait.
@@ -510,7 +516,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
             if offset < 0 {
                 // Negative offsets return `EINVAL`.
-                return this.set_last_error_and_return_i64(LibcError("EINVAL"));
+                return this.set_last_error_and_return(LibcError("EINVAL"), dest);
             } else {
                 SeekFrom::Start(u64::try_from(offset).unwrap())
             }
@@ -519,19 +525,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         } else if whence == this.eval_libc_i32("SEEK_END") {
             SeekFrom::End(i64::try_from(offset).unwrap())
         } else {
-            return this.set_last_error_and_return_i64(LibcError("EINVAL"));
+            return this.set_last_error_and_return(LibcError("EINVAL"), dest);
         };
 
         let communicate = this.machine.communicate();
 
         let Some(fd) = this.machine.fds.get(fd_num) else {
-            return this.set_last_error_and_return_i64(LibcError("EBADF"));
+            return this.set_last_error_and_return(LibcError("EBADF"), dest);
         };
         let result = fd.seek(communicate, seek_from)?.map(|offset| i64::try_from(offset).unwrap());
         drop(fd);
 
         let result = this.try_unwrap_io_result(result)?;
-        interp_ok(Scalar::from_i64(result))
+        this.write_int(result, dest)?;
+        interp_ok(())
     }
 
     fn unlink(&mut self, path_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index 8dcadbed130..c80858c6363 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -317,6 +317,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let res = this.GetFileInformationByHandle(handle, info)?;
                 this.write_scalar(res, dest)?;
             }
+            "DeleteFileW" => {
+                let [file_name] = this.check_shim(abi, sys_conv, link_name, args)?;
+                let res = this.DeleteFileW(file_name)?;
+                this.write_scalar(res, dest)?;
+            }
 
             // Allocation
             "HeapAlloc" => {
diff --git a/src/tools/miri/src/shims/windows/fs.rs b/src/tools/miri/src/shims/windows/fs.rs
index 32bab548969..7561bf45219 100644
--- a/src/tools/miri/src/shims/windows/fs.rs
+++ b/src/tools/miri/src/shims/windows/fs.rs
@@ -371,6 +371,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         interp_ok(this.eval_windows("c", "TRUE"))
     }
+
+    fn DeleteFileW(
+        &mut self,
+        file_name: &OpTy<'tcx>, // LPCWSTR
+    ) -> InterpResult<'tcx, Scalar> {
+        // ^ Returns BOOL (i32 on Windows)
+        let this = self.eval_context_mut();
+        this.assert_target_os("windows", "DeleteFileW");
+        this.check_no_isolation("`DeleteFileW`")?;
+
+        let file_name = this.read_path_from_wide_str(this.read_pointer(file_name)?)?;
+        match std::fs::remove_file(file_name) {
+            Ok(_) => interp_ok(this.eval_windows("c", "TRUE")),
+            Err(e) => {
+                this.set_last_error(e)?;
+                interp_ok(this.eval_windows("c", "FALSE"))
+            }
+        }
+    }
 }
 
 /// Windows FILETIME is measured in 100-nanosecs since 1601
diff --git a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs
index f73c1b6acb7..3da54b91882 100644
--- a/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/ctlz_nonzero.rs
@@ -1,13 +1,8 @@
-#![feature(intrinsics)]
-
-mod rusti {
-    #[rustc_intrinsic]
-    pub unsafe fn ctlz_nonzero<T>(x: T) -> u32;
-}
+#![feature(core_intrinsics)]
 
 pub fn main() {
     unsafe {
-        use crate::rusti::*;
+        use std::intrinsics::*;
 
         ctlz_nonzero(0u8); //~ ERROR: `ctlz_nonzero` called on 0
     }
diff --git a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs
index a41cb8b1553..2b68f6713d8 100644
--- a/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/cttz_nonzero.rs
@@ -1,13 +1,8 @@
-#![feature(intrinsics)]
-
-mod rusti {
-    #[rustc_intrinsic]
-    pub unsafe fn cttz_nonzero<T>(x: T) -> u32;
-}
+#![feature(core_intrinsics)]
 
 pub fn main() {
     unsafe {
-        use crate::rusti::*;
+        use std::intrinsics::*;
 
         cttz_nonzero(0u8); //~ ERROR: `cttz_nonzero` called on 0
     }
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs
index 7ee0117ffb3..831a65966ce 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_inf1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs
index 22bf881cef0..a7032e97430 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_infneg1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs
index 571121f4019..e8c98761956 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nan.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs
index 12600ef6125..c8b29cbcfe9 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_nanneg.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs
index f848a137c27..0996d0244e8 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_neg.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs
index 43ef4a95738..f28227134d8 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs
index 83432c2b77c..9e400b4ad40 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_big2.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs
index 609443e6d4e..9aca349b918 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_32_too_small1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs
index fb3eb11c0bb..54361f6c32c 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_inf1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs
index b46c4777ba7..75f52296367 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs
index 8a3b9dbdc71..20d8fa1ae80 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_infneg2.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs
index e0c826cb046..611a0ade0a5 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_nan.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs
index c7c5bf40226..8ff8c3bee00 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_neg.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs
index fb3d7bda4e4..1f662e6c32a 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs
index 2cf27b33553..fad172801ea 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big2.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs
index 22dca505e64..7eb3559527a 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big3.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs
index b59c8fa8e0c..351fc6c6f1c 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big4.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs
index 4ad0cd343a4..a6f73c79710 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big5.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs
index fd47dfc03d7..b01ff3aafc0 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big6.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs
index 680ebda1c96..a573e4e852c 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_big7.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs
index e4cb36c5d2e..4fb38c9bc2e 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small1.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs
index fe4bac92bd3..c4c0d3c17f0 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small2.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs
index 219efd80316..de7d2215fd6 100644
--- a/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs
+++ b/src/tools/miri/tests/fail/intrinsics/float_to_int_64_too_small3.rs
@@ -1,8 +1,6 @@
-#![feature(intrinsics)]
-
+#![feature(core_intrinsics)]
 // Directly call intrinsic to avoid debug assertions in libstd
-#[rustc_intrinsic]
-unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+use std::intrinsics::float_to_int_unchecked;
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/no_main.stderr b/src/tools/miri/tests/fail/no_main.stderr
index e9b9e5d65b1..e7f63be794f 100644
--- a/src/tools/miri/tests/fail/no_main.stderr
+++ b/src/tools/miri/tests/fail/no_main.stderr
@@ -2,7 +2,7 @@ error: Miri can only run programs that have a main function.
        Alternatively, you can export a `miri_start` function:
        
        #[cfg(miri)]
-       #[no_mangle]
+       #[unsafe(no_mangle)]
        fn miri_start(argc: isize, argv: *const *const u8) -> isize {
            // Call the actual start function that your project implements, based on your target's conventions.
        }
diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs
index 515e467fb54..ac6e221fcd8 100644
--- a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs
+++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs
@@ -9,6 +9,6 @@ extern "C" {
 fn main() {
     let mut fds = [-1, -1];
     let res = unsafe { pipe(fds.as_mut_ptr()) };
-    //~^ ERROR: calling a non-variadic function with a variadic caller-side signature
+    //~^ ERROR: ABI mismatch: calling a non-variadic function with a variadic caller-side signature
     assert_eq!(res, 0);
 }
diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr
index 2782f3b3269..0f642aca322 100644
--- a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr
+++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: calling a non-variadic function with a variadic caller-side signature
+error: Undefined Behavior: ABI mismatch: calling a non-variadic function with a variadic caller-side signature
   --> tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC
    |
 LL |     let res = unsafe { pipe(fds.as_mut_ptr()) };
-   |                        ^^^^^^^^^^^^^^^^^^^^^^ calling a non-variadic function with a variadic caller-side signature
+   |                        ^^^^^^^^^^^^^^^^^^^^^^ ABI mismatch: calling a non-variadic function with a variadic caller-side signature
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
index a015464dbde..698ca4e0b4b 100644
--- a/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
+++ b/src/tools/miri/tests/pass-dep/shims/windows-fs.rs
@@ -2,6 +2,7 @@
 //@compile-flags: -Zmiri-disable-isolation
 #![allow(nonstandard_style)]
 
+use std::io::ErrorKind;
 use std::os::windows::ffi::OsStrExt;
 use std::path::Path;
 use std::ptr;
@@ -15,10 +16,10 @@ use windows_sys::Win32::Foundation::{
     STATUS_IO_DEVICE_ERROR,
 };
 use windows_sys::Win32::Storage::FileSystem::{
-    BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
-    FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT,
-    FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GetFileInformationByHandle, OPEN_ALWAYS,
-    OPEN_EXISTING,
+    BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, DeleteFileW,
+    FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_NORMAL, FILE_FLAG_BACKUP_SEMANTICS,
+    FILE_FLAG_OPEN_REPARSE_POINT, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE,
+    GetFileInformationByHandle, OPEN_ALWAYS, OPEN_EXISTING,
 };
 
 fn main() {
@@ -28,6 +29,7 @@ fn main() {
         test_create_always_twice();
         test_open_always_twice();
         test_open_dir_reparse();
+        test_delete_file();
         test_ntstatus_to_dos();
     }
 }
@@ -194,6 +196,21 @@ unsafe fn test_open_dir_reparse() {
     };
 }
 
+unsafe fn test_delete_file() {
+    let temp = utils::tmp().join("test_delete_file.txt");
+    let raw_path = to_wide_cstr(&temp);
+    let _ = std::fs::File::create(&temp).unwrap();
+
+    if DeleteFileW(raw_path.as_ptr()) == 0 {
+        panic!("Failed to delete file");
+    }
+
+    match std::fs::File::open(temp) {
+        Ok(_) => panic!("File not deleted"),
+        Err(e) => assert!(e.kind() == ErrorKind::NotFound, "File not deleted"),
+    }
+}
+
 unsafe fn test_ntstatus_to_dos() {
     // We won't test all combinations, just a couple common ones
     assert_eq!(RtlNtStatusToDosError(STATUS_IO_DEVICE_ERROR), ERROR_IO_DEVICE);
diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs
index 6d556b77795..4fa84384d9b 100644
--- a/src/tools/miri/tests/pass/async-drop.rs
+++ b/src/tools/miri/tests/pass/async-drop.rs
@@ -4,7 +4,7 @@
 
 // WARNING: If you would ever want to modify this test,
 // please consider modifying rustc's async drop test at
-// `tests/ui/async-await/async-drop.rs`.
+// `tests/ui/async-await/async-drop/async-drop-initial.rs`.
 
 #![feature(async_drop, impl_trait_in_assoc_type)]
 #![allow(incomplete_features, dead_code)]
@@ -68,7 +68,8 @@ fn main() {
         test_async_drop(SyncThenAsync { i: 15, a: AsyncInt(16), b: SyncInt(17), c: AsyncInt(18) })
             .await;
 
-        let async_drop_fut = pin!(core::future::async_drop(AsyncInt(19)));
+        let mut ptr19 = mem::MaybeUninit::new(AsyncInt(19));
+        let async_drop_fut = pin!(unsafe { async_drop_in_place(ptr19.as_mut_ptr()) });
         test_idempotency(async_drop_fut).await;
 
         let foo = AsyncInt(20);
@@ -89,13 +90,14 @@ fn main() {
 
 struct AsyncInt(i32);
 
+impl Drop for AsyncInt {
+    fn drop(&mut self) {
+        println!("AsyncInt::drop: {}", self.0);
+    }
+}
 impl AsyncDrop for AsyncInt {
-    type Dropper<'a> = impl Future<Output = ()>;
-
-    fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> {
-        async move {
-            println!("AsyncInt::Dropper::poll: {}", self.0);
-        }
+    async fn drop(self: Pin<&mut Self>) {
+        println!("AsyncInt::async_drop: {}", self.0);
     }
 }
 
@@ -124,16 +126,14 @@ struct AsyncReference<'a> {
     foo: &'a AsyncInt,
 }
 
+impl Drop for AsyncReference<'_> {
+    fn drop(&mut self) {
+        println!("AsyncReference::drop: {}", self.foo.0);
+    }
+}
 impl AsyncDrop for AsyncReference<'_> {
-    type Dropper<'a>
-        = impl Future<Output = ()>
-    where
-        Self: 'a;
-
-    fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> {
-        async move {
-            println!("AsyncReference::Dropper::poll: {}", self.foo.0);
-        }
+    async fn drop(self: Pin<&mut Self>) {
+        println!("AsyncReference::async_drop: {}", self.foo.0);
     }
 }
 
@@ -145,13 +145,14 @@ struct AsyncStruct {
     b: AsyncInt,
 }
 
+impl Drop for AsyncStruct {
+    fn drop(&mut self) {
+        println!("AsyncStruct::drop: {}", self.i);
+    }
+}
 impl AsyncDrop for AsyncStruct {
-    type Dropper<'a> = impl Future<Output = ()>;
-
-    fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> {
-        async move {
-            println!("AsyncStruct::Dropper::poll: {}", self.i);
-        }
+    async fn drop(self: Pin<&mut Self>) {
+        println!("AsyncStruct::async_drop: {}", self.i);
     }
 }
 
@@ -160,23 +161,34 @@ enum AsyncEnum {
     B(SyncInt),
 }
 
+impl Drop for AsyncEnum {
+    fn drop(&mut self) {
+        let new_self = match self {
+            AsyncEnum::A(foo) => {
+                println!("AsyncEnum(A)::drop: {}", foo.0);
+                AsyncEnum::B(SyncInt(foo.0))
+            }
+            AsyncEnum::B(foo) => {
+                println!("AsyncEnum(B)::drop: {}", foo.0);
+                AsyncEnum::A(AsyncInt(foo.0))
+            }
+        };
+        mem::forget(mem::replace(&mut *self, new_self));
+    }
+}
 impl AsyncDrop for AsyncEnum {
-    type Dropper<'a> = impl Future<Output = ()>;
-
-    fn async_drop(mut self: Pin<&mut Self>) -> Self::Dropper<'_> {
-        async move {
-            let new_self = match &*self {
-                AsyncEnum::A(foo) => {
-                    println!("AsyncEnum(A)::Dropper::poll: {}", foo.0);
-                    AsyncEnum::B(SyncInt(foo.0))
-                }
-                AsyncEnum::B(foo) => {
-                    println!("AsyncEnum(B)::Dropper::poll: {}", foo.0);
-                    AsyncEnum::A(AsyncInt(foo.0))
-                }
-            };
-            mem::forget(mem::replace(&mut *self, new_self));
-        }
+    async fn drop(mut self: Pin<&mut Self>) {
+        let new_self = match &*self {
+            AsyncEnum::A(foo) => {
+                println!("AsyncEnum(A)::async_drop: {}", foo.0);
+                AsyncEnum::B(SyncInt(foo.0))
+            }
+            AsyncEnum::B(foo) => {
+                println!("AsyncEnum(B)::async_drop: {}", foo.0);
+                AsyncEnum::A(AsyncInt(foo.0))
+            }
+        };
+        mem::forget(mem::replace(&mut *self, new_self));
     }
 }
 
@@ -186,14 +198,15 @@ union AsyncUnion {
     unsigned: u32,
 }
 
+impl Drop for AsyncUnion {
+    fn drop(&mut self) {
+        println!("AsyncUnion::drop: {}, {}", unsafe { self.signed }, unsafe { self.unsigned },);
+    }
+}
 impl AsyncDrop for AsyncUnion {
-    type Dropper<'a> = impl Future<Output = ()>;
-
-    fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> {
-        async move {
-            println!("AsyncUnion::Dropper::poll: {}, {}", unsafe { self.signed }, unsafe {
-                self.unsigned
-            });
-        }
+    async fn drop(self: Pin<&mut Self>) {
+        println!("AsyncUnion::async_drop: {}, {}", unsafe { self.signed }, unsafe {
+            self.unsigned
+        });
     }
 }
diff --git a/src/tools/miri/tests/pass/async-drop.stack.stdout b/src/tools/miri/tests/pass/async-drop.stack.stdout
index 9cae4331caf..fc53df2f1b4 100644
--- a/src/tools/miri/tests/pass/async-drop.stack.stdout
+++ b/src/tools/miri/tests/pass/async-drop.stack.stdout
@@ -1,22 +1,23 @@
-AsyncInt::Dropper::poll: 0
-AsyncInt::Dropper::poll: 1
-AsyncInt::Dropper::poll: 2
-AsyncInt::Dropper::poll: 3
-AsyncInt::Dropper::poll: 4
-AsyncStruct::Dropper::poll: 6
-AsyncInt::Dropper::poll: 7
-AsyncInt::Dropper::poll: 8
-AsyncReference::Dropper::poll: 10
-AsyncInt::Dropper::poll: 11
-AsyncEnum(A)::Dropper::poll: 12
+AsyncInt::async_drop: 0
+AsyncInt::async_drop: 1
+AsyncInt::async_drop: 2
+AsyncInt::async_drop: 3
+AsyncInt::async_drop: 4
+AsyncStruct::async_drop: 6
+AsyncInt::async_drop: 7
+AsyncInt::async_drop: 8
+AsyncReference::async_drop: 10
+AsyncInt::async_drop: 11
+AsyncEnum(A)::async_drop: 12
 SyncInt::drop: 12
-AsyncEnum(B)::Dropper::poll: 13
-AsyncInt::Dropper::poll: 13
+AsyncEnum(B)::async_drop: 13
+AsyncInt::async_drop: 13
 SyncInt::drop: 14
 SyncThenAsync::drop: 15
-AsyncInt::Dropper::poll: 16
+AsyncInt::async_drop: 16
 SyncInt::drop: 17
-AsyncInt::Dropper::poll: 18
-AsyncInt::Dropper::poll: 19
-AsyncInt::Dropper::poll: 20
-AsyncUnion::Dropper::poll: 21, 21
+AsyncInt::async_drop: 18
+AsyncInt::async_drop: 19
+AsyncInt::async_drop: 20
+AsyncUnion::async_drop: 21, 21
+AsyncInt::async_drop: 10
diff --git a/src/tools/miri/tests/pass/async-drop.tree.stdout b/src/tools/miri/tests/pass/async-drop.tree.stdout
index 9cae4331caf..fc53df2f1b4 100644
--- a/src/tools/miri/tests/pass/async-drop.tree.stdout
+++ b/src/tools/miri/tests/pass/async-drop.tree.stdout
@@ -1,22 +1,23 @@
-AsyncInt::Dropper::poll: 0
-AsyncInt::Dropper::poll: 1
-AsyncInt::Dropper::poll: 2
-AsyncInt::Dropper::poll: 3
-AsyncInt::Dropper::poll: 4
-AsyncStruct::Dropper::poll: 6
-AsyncInt::Dropper::poll: 7
-AsyncInt::Dropper::poll: 8
-AsyncReference::Dropper::poll: 10
-AsyncInt::Dropper::poll: 11
-AsyncEnum(A)::Dropper::poll: 12
+AsyncInt::async_drop: 0
+AsyncInt::async_drop: 1
+AsyncInt::async_drop: 2
+AsyncInt::async_drop: 3
+AsyncInt::async_drop: 4
+AsyncStruct::async_drop: 6
+AsyncInt::async_drop: 7
+AsyncInt::async_drop: 8
+AsyncReference::async_drop: 10
+AsyncInt::async_drop: 11
+AsyncEnum(A)::async_drop: 12
 SyncInt::drop: 12
-AsyncEnum(B)::Dropper::poll: 13
-AsyncInt::Dropper::poll: 13
+AsyncEnum(B)::async_drop: 13
+AsyncInt::async_drop: 13
 SyncInt::drop: 14
 SyncThenAsync::drop: 15
-AsyncInt::Dropper::poll: 16
+AsyncInt::async_drop: 16
 SyncInt::drop: 17
-AsyncInt::Dropper::poll: 18
-AsyncInt::Dropper::poll: 19
-AsyncInt::Dropper::poll: 20
-AsyncUnion::Dropper::poll: 21, 21
+AsyncInt::async_drop: 18
+AsyncInt::async_drop: 19
+AsyncInt::async_drop: 20
+AsyncUnion::async_drop: 21, 21
+AsyncInt::async_drop: 10
diff --git a/src/tools/miri/tests/pass/dst-raw.rs b/src/tools/miri/tests/pass/dst-raw.rs
index f26191a1d59..3d0b843b3da 100644
--- a/src/tools/miri/tests/pass/dst-raw.rs
+++ b/src/tools/miri/tests/pass/dst-raw.rs
@@ -1,5 +1,7 @@
 // Test DST raw pointers
 
+#![allow(dangerous_implicit_autorefs)]
+
 trait Trait {
     fn foo(&self) -> isize;
 }
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 575d70579a4..98a88cfd62d 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1292,8 +1292,7 @@ fn test_non_determinism() {
             }
         }
         // We saw the same thing N times.
-        // FIXME: temporarily disabled as it breaks std tests.
-        //panic!("expected non-determinism, got {rounds} times the same result: {first:?}");
+        panic!("expected non-determinism, got {rounds} times the same result: {first:?}");
     }
 
     macro_rules! test_operations_f {
@@ -1319,66 +1318,68 @@ fn test_non_determinism() {
     }
     pub fn test_operations_f32(a: f32, b: f32) {
         test_operations_f!(a, b);
-        ensure_nondet(|| a.log(b));
-        ensure_nondet(|| a.exp());
-        ensure_nondet(|| 10f32.exp2());
-        ensure_nondet(|| f32::consts::E.ln());
-        ensure_nondet(|| 1f32.ln_1p());
-        ensure_nondet(|| 10f32.log10());
-        ensure_nondet(|| 8f32.log2());
-        ensure_nondet(|| 27.0f32.cbrt());
-        ensure_nondet(|| 3.0f32.hypot(4.0f32));
-        ensure_nondet(|| 1f32.sin());
-        ensure_nondet(|| 0f32.cos());
-        // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
-        // which means the little rounding errors Miri introduces are discard by the cast down to `f32`.
-        // Just skip the test for them.
-        if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) {
-            ensure_nondet(|| 1.0f32.tan());
-            ensure_nondet(|| 1.0f32.asin());
-            ensure_nondet(|| 5.0f32.acos());
-            ensure_nondet(|| 1.0f32.atan());
-            ensure_nondet(|| 1.0f32.atan2(2.0f32));
-            ensure_nondet(|| 1.0f32.sinh());
-            ensure_nondet(|| 1.0f32.cosh());
-            ensure_nondet(|| 1.0f32.tanh());
-        }
-        ensure_nondet(|| 1.0f32.asinh());
-        ensure_nondet(|| 2.0f32.acosh());
-        ensure_nondet(|| 0.5f32.atanh());
-        ensure_nondet(|| 5.0f32.gamma());
-        ensure_nondet(|| 5.0f32.ln_gamma());
-        ensure_nondet(|| 5.0f32.erf());
-        ensure_nondet(|| 5.0f32.erfc());
+        // FIXME: temporarily disabled as it breaks std tests.
+        // ensure_nondet(|| a.log(b));
+        // ensure_nondet(|| a.exp());
+        // ensure_nondet(|| 10f32.exp2());
+        // ensure_nondet(|| f32::consts::E.ln());
+        // ensure_nondet(|| 1f32.ln_1p());
+        // ensure_nondet(|| 10f32.log10());
+        // ensure_nondet(|| 8f32.log2());
+        // ensure_nondet(|| 27.0f32.cbrt());
+        // ensure_nondet(|| 3.0f32.hypot(4.0f32));
+        // ensure_nondet(|| 1f32.sin());
+        // ensure_nondet(|| 0f32.cos());
+        // // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
+        // // which means the little rounding errors Miri introduces are discard by the cast down to `f32`.
+        // // Just skip the test for them.
+        // if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) {
+        //     ensure_nondet(|| 1.0f32.tan());
+        //     ensure_nondet(|| 1.0f32.asin());
+        //     ensure_nondet(|| 5.0f32.acos());
+        //     ensure_nondet(|| 1.0f32.atan());
+        //     ensure_nondet(|| 1.0f32.atan2(2.0f32));
+        //     ensure_nondet(|| 1.0f32.sinh());
+        //     ensure_nondet(|| 1.0f32.cosh());
+        //     ensure_nondet(|| 1.0f32.tanh());
+        // }
+        // ensure_nondet(|| 1.0f32.asinh());
+        // ensure_nondet(|| 2.0f32.acosh());
+        // ensure_nondet(|| 0.5f32.atanh());
+        // ensure_nondet(|| 5.0f32.gamma());
+        // ensure_nondet(|| 5.0f32.ln_gamma());
+        // ensure_nondet(|| 5.0f32.erf());
+        // ensure_nondet(|| 5.0f32.erfc());
     }
     pub fn test_operations_f64(a: f64, b: f64) {
         test_operations_f!(a, b);
-        ensure_nondet(|| a.log(b));
-        ensure_nondet(|| a.exp());
-        ensure_nondet(|| 50f64.exp2());
-        ensure_nondet(|| 3f64.ln());
-        ensure_nondet(|| 1f64.ln_1p());
-        ensure_nondet(|| f64::consts::E.log10());
-        ensure_nondet(|| f64::consts::E.log2());
-        ensure_nondet(|| 27.0f64.cbrt());
-        ensure_nondet(|| 3.0f64.hypot(4.0f64));
-        ensure_nondet(|| 1f64.sin());
-        ensure_nondet(|| 0f64.cos());
-        ensure_nondet(|| 1.0f64.tan());
-        ensure_nondet(|| 1.0f64.asin());
-        ensure_nondet(|| 5.0f64.acos());
-        ensure_nondet(|| 1.0f64.atan());
-        ensure_nondet(|| 1.0f64.atan2(2.0f64));
-        ensure_nondet(|| 1.0f64.sinh());
-        ensure_nondet(|| 1.0f64.cosh());
-        ensure_nondet(|| 1.0f64.tanh());
-        ensure_nondet(|| 1.0f64.asinh());
-        ensure_nondet(|| 3.0f64.acosh());
-        ensure_nondet(|| 0.5f64.atanh());
-        ensure_nondet(|| 5.0f64.gamma());
-        ensure_nondet(|| 5.0f64.ln_gamma());
-        ensure_nondet(|| 5.0f64.erf());
-        ensure_nondet(|| 5.0f64.erfc());
+        // FIXME: temporarily disabled as it breaks std tests.
+        // ensure_nondet(|| a.log(b));
+        // ensure_nondet(|| a.exp());
+        // ensure_nondet(|| 50f64.exp2());
+        // ensure_nondet(|| 3f64.ln());
+        // ensure_nondet(|| 1f64.ln_1p());
+        // ensure_nondet(|| f64::consts::E.log10());
+        // ensure_nondet(|| f64::consts::E.log2());
+        // ensure_nondet(|| 27.0f64.cbrt());
+        // ensure_nondet(|| 3.0f64.hypot(4.0f64));
+        // ensure_nondet(|| 1f64.sin());
+        // ensure_nondet(|| 0f64.cos());
+        // ensure_nondet(|| 1.0f64.tan());
+        // ensure_nondet(|| 1.0f64.asin());
+        // ensure_nondet(|| 5.0f64.acos());
+        // ensure_nondet(|| 1.0f64.atan());
+        // ensure_nondet(|| 1.0f64.atan2(2.0f64));
+        // ensure_nondet(|| 1.0f64.sinh());
+        // ensure_nondet(|| 1.0f64.cosh());
+        // ensure_nondet(|| 1.0f64.tanh());
+        // ensure_nondet(|| 1.0f64.asinh());
+        // ensure_nondet(|| 3.0f64.acosh());
+        // ensure_nondet(|| 0.5f64.atanh());
+        // ensure_nondet(|| 5.0f64.gamma());
+        // ensure_nondet(|| 5.0f64.ln_gamma());
+        // ensure_nondet(|| 5.0f64.erf());
+        // ensure_nondet(|| 5.0f64.erfc());
     }
     pub fn test_operations_f128(a: f128, b: f128) {
         test_operations_f!(a, b);
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 6ad23055f30..d0a7f245ee0 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -17,10 +17,10 @@ mod utils;
 
 fn main() {
     test_path_conversion();
+    test_file_create_new();
     // Windows file handling is very incomplete.
     if cfg!(not(windows)) {
         test_file();
-        test_file_create_new();
         test_seek();
         test_file_clone();
         test_metadata();
diff --git a/src/tools/miri/tests/pass/slices.rs b/src/tools/miri/tests/pass/slices.rs
index dd18a061cdd..686683c3a25 100644
--- a/src/tools/miri/tests/pass/slices.rs
+++ b/src/tools/miri/tests/pass/slices.rs
@@ -1,7 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(slice_as_chunks)]
 #![feature(slice_partition_dedup)]
 #![feature(layout_for_ptr)]
 
@@ -227,7 +226,7 @@ fn test_for_invalidated_pointers() {
 
     buffer.reverse();
 
-    // Calls `fn as_chunks_unchecked_mut` internally (requires unstable `#![feature(slice_as_chunks)]`):
+    // Calls `fn as_chunks_unchecked_mut` internally:
     assert_eq!(2, buffer.as_chunks_mut::<32>().0.len());
     for chunk in buffer.as_chunks_mut::<32>().0 {
         for elem in chunk {
diff --git a/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs b/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs
index 830e9c33847..e86cb3711ac 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/interior_mutability.rs
@@ -1,3 +1,5 @@
+#![allow(dangerous_implicit_autorefs)]
+
 use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
 use std::mem::{self, MaybeUninit};
 
diff --git a/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs
new file mode 100644
index 00000000000..6dde593d2cf
--- /dev/null
+++ b/src/tools/miri/tests/pass/tree_borrows/interior_mutability.rs
@@ -0,0 +1,178 @@
+//@revisions: default uniq
+//@compile-flags: -Zmiri-tree-borrows
+//@[uniq]compile-flags: -Zmiri-unique-is-unique
+#![allow(dangerous_implicit_autorefs)]
+use std::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
+use std::mem::{self, MaybeUninit};
+
+fn main() {
+    aliasing_mut_and_shr();
+    aliasing_frz_and_shr();
+    into_interior_mutability();
+    unsafe_cell_2phase();
+    unsafe_cell_deallocate();
+    unsafe_cell_invalidate();
+    refcell_basic();
+    ref_protector();
+    ref_mut_protector();
+    rust_issue_68303();
+}
+
+fn aliasing_mut_and_shr() {
+    fn inner(rc: &RefCell<i32>, aliasing: &mut i32) {
+        *aliasing += 4;
+        let _escape_to_raw = rc as *const _;
+        *aliasing += 4;
+        let _shr = &*rc;
+        *aliasing += 4;
+        // also turning this into a frozen ref now must work
+        let aliasing = &*aliasing;
+        let _val = *aliasing;
+        let _escape_to_raw = rc as *const _; // this must NOT unfreeze
+        let _val = *aliasing;
+        let _shr = &*rc; // this must NOT unfreeze
+        let _val = *aliasing;
+    }
+
+    let rc = RefCell::new(23);
+    let mut bmut = rc.borrow_mut();
+    inner(&rc, &mut *bmut);
+    drop(bmut);
+    assert_eq!(*rc.borrow(), 23 + 12);
+}
+
+fn aliasing_frz_and_shr() {
+    fn inner(rc: &RefCell<i32>, aliasing: &i32) {
+        let _val = *aliasing;
+        let _escape_to_raw = rc as *const _; // this must NOT unfreeze
+        let _val = *aliasing;
+        let _shr = &*rc; // this must NOT unfreeze
+        let _val = *aliasing;
+    }
+
+    let rc = RefCell::new(23);
+    let bshr = rc.borrow();
+    inner(&rc, &*bshr);
+    assert_eq!(*rc.borrow(), 23);
+}
+
+// Getting a pointer into a union with interior mutability used to be tricky
+// business (https://github.com/rust-lang/miri/issues/615), but it should work
+// now.
+fn into_interior_mutability() {
+    let mut x: MaybeUninit<(Cell<u32>, u32)> = MaybeUninit::uninit();
+    x.as_ptr();
+    x.write((Cell::new(0), 1));
+    let ptr = unsafe { x.assume_init_ref() };
+    assert_eq!(ptr.1, 1);
+}
+
+// Two-phase borrows of the pointer returned by UnsafeCell::get() should not
+// invalidate aliases.
+fn unsafe_cell_2phase() {
+    unsafe {
+        let x = &UnsafeCell::new(vec![]);
+        let x2 = &*x;
+        (*x.get()).push(0);
+        let _val = (*x2.get()).get(0);
+    }
+}
+
+/// Make sure we can deallocate an UnsafeCell that was passed to an active fn call.
+/// (This is the fix for https://github.com/rust-lang/rust/issues/55005.)
+fn unsafe_cell_deallocate() {
+    fn f(x: &UnsafeCell<i32>) {
+        let b: Box<i32> = unsafe { Box::from_raw(x as *const _ as *mut i32) };
+        drop(b)
+    }
+
+    let b = Box::new(0i32);
+    f(unsafe { mem::transmute(Box::into_raw(b)) });
+}
+
+/// As a side-effect of the above, we also allow this -- at least for now.
+fn unsafe_cell_invalidate() {
+    fn f(_x: &UnsafeCell<i32>, y: *mut i32) {
+        // Writing to y invalidates x, but that is okay.
+        unsafe {
+            *y += 1;
+        }
+    }
+
+    let mut x = 0i32;
+    let raw1 = &mut x as *mut _;
+    let ref1 = unsafe { &mut *raw1 };
+    let raw2 = ref1 as *mut _;
+    // Now the borrow stack is: raw1, ref2, raw2.
+    // So using raw1 invalidates raw2.
+    f(unsafe { mem::transmute(raw2) }, raw1);
+}
+
+fn refcell_basic() {
+    let c = RefCell::new(42);
+    {
+        let s1 = c.borrow();
+        let _x: i32 = *s1;
+        let s2 = c.borrow();
+        let _x: i32 = *s1;
+        let _y: i32 = *s2;
+        let _x: i32 = *s1;
+        let _y: i32 = *s2;
+    }
+    {
+        let mut m = c.borrow_mut();
+        let _z: i32 = *m;
+        {
+            let s: &i32 = &*m;
+            let _x = *s;
+        }
+        *m = 23;
+        let _z: i32 = *m;
+    }
+    {
+        let s1 = c.borrow();
+        let _x: i32 = *s1;
+        let s2 = c.borrow();
+        let _x: i32 = *s1;
+        let _y: i32 = *s2;
+        let _x: i32 = *s1;
+        let _y: i32 = *s2;
+    }
+}
+
+// Adding a Stacked Borrows protector for `Ref` would break this
+fn ref_protector() {
+    fn break_it(rc: &RefCell<i32>, r: Ref<'_, i32>) {
+        // `r` has a shared reference, it is passed in as argument and hence
+        // a protector is added that marks this memory as read-only for the entire
+        // duration of this function.
+        drop(r);
+        // *oops* here we can mutate that memory.
+        *rc.borrow_mut() = 2;
+    }
+
+    let rc = RefCell::new(0);
+    break_it(&rc, rc.borrow())
+}
+
+fn ref_mut_protector() {
+    fn break_it(rc: &RefCell<i32>, r: RefMut<'_, i32>) {
+        // `r` has a shared reference, it is passed in as argument and hence
+        // a protector is added that marks this memory as inaccessible for the entire
+        // duration of this function
+        drop(r);
+        // *oops* here we can mutate that memory.
+        *rc.borrow_mut() = 2;
+    }
+
+    let rc = RefCell::new(0);
+    break_it(&rc, rc.borrow_mut())
+}
+
+/// Make sure we do not have bad enum layout optimizations.
+fn rust_issue_68303() {
+    let optional = Some(RefCell::new(false));
+    let mut handle = optional.as_ref().unwrap().borrow_mut();
+    assert!(optional.is_some());
+    *handle = true;
+}
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index d257988a57a..8d6c8284e44 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -2039,9 +2039,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "salsa"
-version = "0.21.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4deeb38b4c80ac90a8d4796f83da941b0d76c23783550d15d37eb43ccddcb5bc"
+checksum = "6f80d5cf3c3fcab2cef898012f242a670477a1baa609267376af9cb4409026c5"
 dependencies = [
  "boxcar",
  "crossbeam-queue",
@@ -2062,15 +2062,15 @@ dependencies = [
 
 [[package]]
 name = "salsa-macro-rules"
-version = "0.21.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e6166fa2802d86a77dbcae1bfe75f0ac46fdf952660c233ed64855a53dd603"
+checksum = "05303d72606fbf2b9c9523cda2039bb8ecb00304027a3cd7e52b02a65c7d9185"
 
 [[package]]
 name = "salsa-macros"
-version = "0.21.0"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf358e645a835d9901ee4d812d9812266e046ee92a28d2e37a73b7169a6503b7"
+checksum = "eb2f0e2a30c65cb3cd63440c491dde68d9af7e1be2b77832ac7057141107db50"
 dependencies = [
  "heck",
  "proc-macro2",
diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
index 6b81928c91e..357e56ddfaa 100644
--- a/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/query-group-macro/src/lib.rs
@@ -159,7 +159,7 @@ impl Parse for Cycle {
         }
 
         impl Parse for Option {
-            fn parse(input: ParseStream) -> syn::Result<Self> {
+            fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
                 let name = input.parse()?;
                 input.parse::<Token![=]>()?;
                 let value = input.parse()?;
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 09c127f6bcd..90e4d65bf96 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-21079f53a359d9fc82668d4175d49dafdb600563
+6e23095adf9209614a45f7f75fea36dad7b92afb
diff --git a/src/tools/rustfmt/src/pairs.rs b/src/tools/rustfmt/src/pairs.rs
index 9c51298416b..17ff041d775 100644
--- a/src/tools/rustfmt/src/pairs.rs
+++ b/src/tools/rustfmt/src/pairs.rs
@@ -1,4 +1,4 @@
-use rustc_ast::ast;
+use rustc_ast::{ast, token};
 use rustc_span::Span;
 
 use crate::config::IndentStyle;
@@ -272,13 +272,17 @@ struct PairList<'a, 'b, T: Rewrite> {
     span: Span,
 }
 
-fn is_ident(expr: &ast::Expr) -> bool {
+fn is_ident_or_bool_lit(expr: &ast::Expr) -> bool {
     match &expr.kind {
         ast::ExprKind::Path(None, path) if path.segments.len() == 1 => true,
+        ast::ExprKind::Lit(token::Lit {
+            kind: token::LitKind::Bool,
+            ..
+        }) => true,
         ast::ExprKind::Unary(_, expr)
         | ast::ExprKind::AddrOf(_, _, expr)
         | ast::ExprKind::Paren(expr)
-        | ast::ExprKind::Try(expr) => is_ident(expr),
+        | ast::ExprKind::Try(expr) => is_ident_or_bool_lit(expr),
         _ => false,
     }
 }
@@ -296,10 +300,10 @@ impl<'a, 'b> PairList<'a, 'b, ast::Expr> {
             return false;
         }
 
-        let fist_item_is_ident = is_ident(self.list[0].0);
+        let fist_item_is_ident_or_bool_lit = is_ident_or_bool_lit(self.list[0].0);
         let second_item_is_let_chain = matches!(self.list[1].0.kind, ast::ExprKind::Let(..));
 
-        fist_item_is_ident && second_item_is_let_chain
+        fist_item_is_ident_or_bool_lit && second_item_is_let_chain
     }
 }
 
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 75a5a8532b8..7ec1032dcb4 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -1093,6 +1093,19 @@ impl Rewrite for ast::TyPat {
             ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => {
                 rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
             }
+            ast::TyPatKind::Or(ref variants) => {
+                let mut first = true;
+                let mut s = String::new();
+                for variant in variants {
+                    if first {
+                        first = false
+                    } else {
+                        s.push_str(" | ");
+                    }
+                    s.push_str(&variant.rewrite_result(context, shape)?);
+                }
+                Ok(s)
+            }
             ast::TyPatKind::Err(_) => Err(RewriteError::Unknown),
         }
     }
diff --git a/src/tools/rustfmt/tests/source/let_chains.rs b/src/tools/rustfmt/tests/source/let_chains.rs
index b7c1f811096..0c4d8aa85ea 100644
--- a/src/tools/rustfmt/tests/source/let_chains.rs
+++ b/src/tools/rustfmt/tests/source/let_chains.rs
@@ -20,6 +20,11 @@ fn test_single_line_let_chain() {
     if a && let Some(b) = foo() {
     }
 
+    // first item in let-chain is a bool literal
+    if true && let Some(x) = y {
+
+    }
+
     // first item in let-chain is a unary ! with an ident
     let unary_not = if !from_hir_call
         && let Some(p) = parent
@@ -94,11 +99,6 @@ fn test_multi_line_let_chain() {
 
     }
 
-    // bool literal
-    if true && let Some(x) = y {
-
-    }
-
     // cast to a bool
     if 1 as bool && let Some(x) = y {
 
diff --git a/src/tools/rustfmt/tests/target/let_chains.rs b/src/tools/rustfmt/tests/target/let_chains.rs
index 1ceecac8abc..204937b4cac 100644
--- a/src/tools/rustfmt/tests/target/let_chains.rs
+++ b/src/tools/rustfmt/tests/target/let_chains.rs
@@ -50,6 +50,9 @@ fn test_single_line_let_chain() {
     // first item in let-chain is an ident
     if a && let Some(b) = foo() {}
 
+    // first item in let-chain is a bool literal
+    if true && let Some(x) = y {}
+
     // first item in let-chain is a unary ! with an ident
     let unary_not = if !from_hir_call && let Some(p) = parent {};
 
@@ -102,11 +105,6 @@ fn test_multi_line_let_chain() {
         && let Some(x) = y
     {}
 
-    // bool literal
-    if true
-        && let Some(x) = y
-    {}
-
     // cast to a bool
     if 1 as bool
         && let Some(x) = y
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index f1ce3ccda04..e6b5aa59622 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -1979,7 +1979,6 @@ ui/issues/issue-27997.rs
 ui/issues/issue-28105.rs
 ui/issues/issue-28109.rs
 ui/issues/issue-28181.rs
-ui/issues/issue-2823.rs
 ui/issues/issue-28279.rs
 ui/issues/issue-28344.rs
 ui/issues/issue-28433.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 2e069af23d6..44dd1e50f5b 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use ignore::Walk;
 const ENTRY_LIMIT: u32 = 901;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1626;
+const ISSUES_ENTRY_LIMIT: u32 = 1624;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files