about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-03-28 20:56:37 +0000
committerbors <bors@rust-lang.org>2025-03-28 20:56:37 +0000
commit920d95eaf23d7eb6b415d09868e4f793024fa604 (patch)
tree6f1daf8f0aa4ea0176049619d2d53b4fce65e32f
parent19f42cb9bb65555e7d95dab7d17573ae6c5d634c (diff)
parent20f265525864130cfb3db4154aa005212424d873 (diff)
downloadrust-920d95eaf23d7eb6b415d09868e4f793024fa604.tar.gz
rust-920d95eaf23d7eb6b415d09868e4f793024fa604.zip
Auto merge of #139085 - matthiaskrgr:rollup-3q2peol, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #138976 (Explain one-past-the-end pointer in std library)
 - #139052 (Put pin!() tests in the right file.)
 - #139058 (Fix formatting nit in process.rs)
 - #139063 (Fix TAIT & ATPIT feature gating in the presence of anon consts)
 - #139065 (Miri subtree update)
 - #139069 (`io::Take`: avoid new `BorrowedBuf` creation in some case)
 - #139075 (Do not treat lifetimes from parent items as influencing child items)
 - #139079 (tracking autodiff files via triagebot.toml)

Failed merges:

 - #139044 (bootstrap: Avoid cloning `change-id` list)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock30
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs7
-rw-r--r--compiler/rustc_resolve/src/late.rs5
-rw-r--r--library/core/src/ptr/const_ptr.rs3
-rw-r--r--library/coretests/tests/pin.rs14
-rw-r--r--library/coretests/tests/pin_macro.rs17
-rw-r--r--library/std/src/io/mod.rs8
-rw-r--r--library/std/src/process.rs2
-rw-r--r--src/tools/miri/.github/workflows/sysroots.yml1
-rw-r--r--src/tools/miri/Cargo.lock4
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/README.md6
-rw-r--r--src/tools/miri/bench-cargo-miri/mse/src/main.rs2
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs2
-rwxr-xr-xsrc/tools/miri/ci/ci.sh2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs7
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/diagnostics.rs4
-rw-r--r--src/tools/miri/src/eval.rs1
-rw-r--r--src/tools/miri/src/helpers.rs94
-rw-r--r--src/tools/miri/src/machine.rs8
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs55
-rw-r--r--src/tools/miri/src/shims/panic.rs3
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs11
-rw-r--r--src/tools/miri/tests/fail/shims/input_arg_mismatch.rs21
-rw-r--r--src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr17
-rw-r--r--src/tools/miri/tests/fail/shims/return_type_mismatch.rs21
-rw-r--r--src/tools/miri/tests/fail/shims/return_type_mismatch.stderr17
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs6
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-pipe.rs8
-rw-r--r--src/tools/miri/tests/pass/float.rs1
-rw-r--r--tests/ui/consts/static-default-lifetime/static-trait-impl.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr20
-rw-r--r--tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs26
-rw-r--r--tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr111
-rw-r--r--tests/ui/impl-trait/impl_trait_projections.rs5
-rw-r--r--tests/ui/impl-trait/impl_trait_projections.stderr10
-rw-r--r--tests/ui/impl-trait/inside-item-nested-in-anon-const.rs25
-rw-r--r--triagebot.toml27
41 files changed, 501 insertions, 128 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7ac73a1c981..a5d8d6f86d7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -535,7 +535,7 @@ dependencies = [
  "termize",
  "tokio",
  "toml 0.7.8",
- "ui_test 0.29.2",
+ "ui_test",
  "walkdir",
 ]
 
@@ -2262,7 +2262,7 @@ dependencies = [
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
- "ui_test 0.28.0",
+ "ui_test",
  "windows-sys 0.52.0",
 ]
 
@@ -5510,32 +5510,6 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
 
 [[package]]
 name = "ui_test"
-version = "0.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
-dependencies = [
- "annotate-snippets 0.11.5",
- "anyhow",
- "bstr",
- "cargo-platform",
- "cargo_metadata 0.18.1",
- "color-eyre",
- "colored",
- "comma",
- "crossbeam-channel",
- "indicatif",
- "levenshtein",
- "prettydiff",
- "regex",
- "rustc_version",
- "rustfix",
- "serde",
- "serde_json",
- "spanned",
-]
-
-[[package]]
-name = "ui_test"
 version = "0.29.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1211b1111c752c73b33073d2958072be08825fd97c9ab4d83444da361a06634b"
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 31ff102c127..a3fcc110a16 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -99,6 +99,13 @@ impl<'a> PostExpansionVisitor<'a> {
                 }
                 visit::walk_ty(self, ty);
             }
+
+            fn visit_anon_const(&mut self, _: &ast::AnonConst) -> Self::Result {
+                // We don't walk the anon const because it crosses a conceptual boundary: We're no
+                // longer "inside" the original type.
+                // Brittle: We assume that the callers of `check_impl_trait` will later recurse into
+                // the items found in the AnonConst to look for nested TyAliases.
+            }
         }
         ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty);
     }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 533e216ddb2..0d23ae501f0 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1833,7 +1833,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 }
                 LifetimeRibKind::StaticIfNoLifetimeInScope { lint_id: node_id, emit_lint } => {
                     let mut lifetimes_in_scope = vec![];
-                    for rib in &self.lifetime_ribs[..i] {
+                    for rib in self.lifetime_ribs[..i].iter().rev() {
                         lifetimes_in_scope.extend(rib.bindings.iter().map(|(ident, _)| ident.span));
                         // Consider any anonymous lifetimes, too
                         if let LifetimeRibKind::AnonymousCreateParameter { binder, .. } = rib.kind
@@ -1841,6 +1841,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         {
                             lifetimes_in_scope.extend(extra.iter().map(|(ident, _, _)| ident.span));
                         }
+                        if let LifetimeRibKind::Item = rib.kind {
+                            break;
+                        }
                     }
                     if lifetimes_in_scope.is_empty() {
                         self.record_lifetime_res(
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 7d0839aff3f..71a84aff246 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -386,7 +386,8 @@ impl<T: ?Sized> *const T {
     /// * If the computed offset is non-zero, then `self` must be [derived from][crate::ptr#provenance] a pointer to some
     ///   [allocated object], and the entire memory range between `self` and the result must be in
     ///   bounds of that allocated object. In particular, this range must not "wrap around" the edge
-    ///   of the address space.
+    ///   of the address space. Note that "range" here refers to a half-open range as usual in Rust,
+    ///   i.e., `self..result` for non-negative offsets and `result..self` for negative offsets.
     ///
     /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
     /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement.
diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs
index a866cf12a3b..b3fb06e710d 100644
--- a/library/coretests/tests/pin.rs
+++ b/library/coretests/tests/pin.rs
@@ -34,9 +34,6 @@ fn pin_const() {
     }
 
     pin_mut_const();
-
-    // Check that we accept a Rust 2024 $expr.
-    std::pin::pin!(const { 1 });
 }
 
 #[allow(unused)]
@@ -84,14 +81,3 @@ mod pin_coerce_unsized {
         arg
     }
 }
-
-#[test]
-#[cfg(not(bootstrap))]
-fn temp_lifetime() {
-    // Check that temporary lifetimes work as in Rust 2021.
-    // Regression test for https://github.com/rust-lang/rust/issues/138596
-    match std::pin::pin!(foo(&mut 0)) {
-        _ => {}
-    }
-    async fn foo(_: &mut usize) {}
-}
diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs
index 43542397a61..639eab740c0 100644
--- a/library/coretests/tests/pin_macro.rs
+++ b/library/coretests/tests/pin_macro.rs
@@ -30,3 +30,20 @@ fn unsize_coercion() {
     let dyn_obj: Pin<&mut dyn Send> = pin!([PhantomPinned; 2]);
     stuff(dyn_obj);
 }
+
+#[test]
+fn rust_2024_expr() {
+    // Check that we accept a Rust 2024 $expr.
+    std::pin::pin!(const { 1 });
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+fn temp_lifetime() {
+    // Check that temporary lifetimes work as in Rust 2021.
+    // Regression test for https://github.com/rust-lang/rust/issues/138596
+    match std::pin::pin!(foo(&mut 0)) {
+        _ => {}
+    }
+    async fn foo(_: &mut usize) {}
+}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 6579b6887aa..314cbb45d49 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2989,11 +2989,11 @@ impl<T: Read> Read for Take<T> {
             return Ok(());
         }
 
-        if self.limit <= buf.capacity() as u64 {
-            // if we just use an as cast to convert, limit may wrap around on a 32 bit target
-            let limit = cmp::min(self.limit, usize::MAX as u64) as usize;
+        if self.limit < buf.capacity() as u64 {
+            // The condition above guarantees that `self.limit` fits in `usize`.
+            let limit = self.limit as usize;
 
-            let extra_init = cmp::min(limit as usize, buf.init_ref().len());
+            let extra_init = cmp::min(limit, buf.init_ref().len());
 
             // SAFETY: no uninit data is written to ibuf
             let ibuf = unsafe { &mut buf.as_mut()[..limit] };
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f81ce8e1a1a..3b765a9537b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1836,7 +1836,7 @@ impl crate::sealed::Sealed for ExitStatusError {}
 /// # if cfg!(unix) {
 /// use std::process::{Command, ExitStatusError};
 ///
-/// fn run(cmd: &str) -> Result<(),ExitStatusError> {
+/// fn run(cmd: &str) -> Result<(), ExitStatusError> {
 ///     Command::new(cmd).status().unwrap().exit_ok()?;
 ///     Ok(())
 /// }
diff --git a/src/tools/miri/.github/workflows/sysroots.yml b/src/tools/miri/.github/workflows/sysroots.yml
index 6a4f44ddd50..11bcaec9255 100644
--- a/src/tools/miri/.github/workflows/sysroots.yml
+++ b/src/tools/miri/.github/workflows/sysroots.yml
@@ -16,6 +16,7 @@ jobs:
       - uses: actions/checkout@v4
       - name: Build the sysroots
         run: |
+          rustup toolchain install nightly
           cargo install -f rustup-toolchain-install-master
           ./miri toolchain -c rust-docs # Docs are the only place targets are separated by tier
           ./miri install
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 57a757f9085..b8100d0e7ad 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -1079,9 +1079,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
 name = "ui_test"
-version = "0.28.0"
+version = "0.29.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
+checksum = "14bf63f2931a28a04af0bd24c5f850223d29f3a40afae49ed6ce442a65eb8652"
 dependencies = [
  "annotate-snippets",
  "anyhow",
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 728a7552fd8..5d8c9a86644 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -47,7 +47,7 @@ windows-sys = { version = "0.52", features = [
 ] }
 
 [dev-dependencies]
-ui_test = "0.28.0"
+ui_test = "0.29.1"
 colored = "2"
 rustc_version = "0.4"
 regex = "1.5.5"
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 4ae901be9b4..201aa1f5386 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -237,8 +237,7 @@ inherent interpreter slowdown and a loss of parallelism.
 You can get your test suite's parallelism back by running `cargo miri nextest run -jN`
 (note that you will need [`cargo-nextest`](https://nexte.st) installed).
 This works because `cargo-nextest` collects a list of all tests then launches a
-separate `cargo miri run` for each test. You will need to specify a `-j` or `--test-threads`;
-by default `cargo miri nextest run` runs one test at a time. For more details, see the
+separate `cargo miri run` for each test. For more information about nextest, see the
 [`cargo-nextest` Miri documentation](https://nexte.st/book/miri.html).
 
 Note: This one-test-per-process model means that `cargo miri test` is able to detect data
@@ -432,7 +431,8 @@ to Miri failing to detect cases of undefined behavior in a program.
 * `-Zmiri-track-weak-memory-loads` shows a backtrace when weak memory emulation returns an outdated
   value from a load. This can help diagnose problems that disappear under
   `-Zmiri-disable-weak-memory-emulation`.
-* `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules.
+* <a name="-Zmiri-tree-borrows"><!-- The playground links here --></a>
+  `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules.
   Tree Borrows is even more experimental than Stacked Borrows. While Tree Borrows
   is still sound in the sense of catching all aliasing violations that current versions
   of the compiler might exploit, it is likely that the eventual final aliasing model
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 e16ccd2c0d7..06d5487d1d4 100644
--- a/src/tools/miri/bench-cargo-miri/mse/src/main.rs
+++ b/src/tools/miri/bench-cargo-miri/mse/src/main.rs
@@ -10,7 +10,7 @@ fn main() {
 }
 
 fn read_i16(buffer: &[u8], index: usize) -> i16 {
-    const SIZE: usize = std::mem::size_of::<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) }
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index d7b4421061c..71ea07f3463 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -467,7 +467,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
                 if let Some(i) = val.iter().position(|&s| s == "link") {
                     emit_link_hack = true;
                     val.remove(i);
-                    if !val.iter().any(|&s| s == "metadata") {
+                    if !val.contains(&"metadata") {
                         val.push("metadata");
                     }
                 }
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 3327ad17c44..7155d692ee5 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -166,7 +166,7 @@ case $HOST_TARGET in
     UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
     TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
     TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread epoll eventfd
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync concurrency thread epoll eventfd
     TEST_TARGET=wasm32-wasip2          run_tests_minimal $BASIC wasm
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index b3e207f53b8..cf36b6fd038 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-f5729cfed3c45e061e8a443677fc1d5ef9277df7
+4ac032f857b46037b55c1fc0fa702450aad37f43
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 0a2d3ac63a7..c263e86c082 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -170,20 +170,22 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // This ensures the interpreted program and native code have the same view of memory.
             let base_ptr = match info.kind {
                 AllocKind::LiveData => {
-                    if this.tcx.try_get_global_alloc(alloc_id).is_some() {
+                    if memory_kind == MiriMemoryKind::Global.into() {
                         // For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
                         let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align)
                             .unwrap_or_else(|| {
                                 panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes", size = info.size)
                             });
                         let ptr = prepared_bytes.as_ptr();
-                        // Store prepared allocation space to be picked up for use later.
+                        // Store prepared allocation to be picked up for use later.
                         global_state
                             .prepared_alloc_bytes
                             .try_insert(alloc_id, prepared_bytes)
                             .unwrap();
                         ptr
                     } else {
+                        // Non-global allocations are already in memory at this point so
+                        // we can just get a pointer to where their data is stored.
                         this.get_alloc_bytes_unchecked_raw(alloc_id)?
                     }
                 }
@@ -381,6 +383,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         align: Align,
     ) -> InterpResult<'tcx, MiriAllocBytes> {
         let this = self.eval_context_ref();
+        assert!(this.tcx.try_get_global_alloc(id).is_some());
         if this.machine.native_lib.is_some() {
             // 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
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index a8a2491304d..94629964ea6 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -1150,7 +1150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         loop {
             if CTRL_C_RECEIVED.load(Relaxed) {
                 this.machine.handle_abnormal_termination();
-                std::process::exit(1);
+                throw_machine_stop!(TerminationInfo::Interrupted);
             }
             match this.machine.threads.schedule(&this.machine.clock)? {
                 SchedulingAction::ExecuteStep => {
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 1a12d4139c7..014b1299f2d 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -16,6 +16,8 @@ pub enum TerminationInfo {
         leak_check: bool,
     },
     Abort(String),
+    /// Miri was interrupted by a Ctrl+C from the user
+    Interrupted,
     UnsupportedInIsolation(String),
     StackedBorrowsUb {
         msg: String,
@@ -63,6 +65,7 @@ impl fmt::Display for TerminationInfo {
         match self {
             Exit { code, .. } => write!(f, "the evaluated program completed with exit code {code}"),
             Abort(msg) => write!(f, "{msg}"),
+            Interrupted => write!(f, "interpretation was interrupted"),
             UnsupportedInIsolation(msg) => write!(f, "{msg}"),
             Int2PtrWithStrictProvenance =>
                 write!(
@@ -226,6 +229,7 @@ pub fn report_error<'tcx>(
         let title = match info {
             &Exit { code, leak_check } => return Some((code, leak_check)),
             Abort(_) => Some("abnormal termination"),
+            Interrupted => None,
             UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance | UnsupportedForeignItem(_) =>
                 Some("unsupported operation"),
             StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } =>
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 36b15dbf623..ed13f670a90 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -434,7 +434,6 @@ pub fn create_ecx<'tcx>(
 /// Evaluates the entry function specified by `entry_id`.
 /// Returns `Some(return_code)` if program execution completed.
 /// Returns `None` if an evaluation error occurred.
-#[expect(clippy::needless_lifetimes)]
 pub fn eval_entry<'tcx>(
     tcx: TyCtxt<'tcx>,
     entry_id: DefId,
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 12e7d0f1a62..29ed94a2e4a 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -14,9 +14,10 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
-use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
+use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
 use rustc_session::config::CrateType;
 use rustc_span::{Span, Symbol};
+use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
 use crate::*;
@@ -994,10 +995,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         exp_abi: Conv,
         link_name: Symbol,
         args: &'a [OpTy<'tcx>],
-    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
-    where
-        &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
-    {
+    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
         self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
 
         if abi.c_variadic {
@@ -1015,6 +1013,80 @@ 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
+    /// arguments.
+    fn check_shim_abi<'a, const N: usize>(
+        &mut self,
+        link_name: Symbol,
+        caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
+        callee_abi: ExternAbi,
+        callee_input_tys: [Ty<'tcx>; N],
+        callee_output_ty: Ty<'tcx>,
+        caller_args: &'a [OpTy<'tcx>],
+    ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
+        let this = self.eval_context_mut();
+        let mut inputs_and_output = callee_input_tys.to_vec();
+        inputs_and_output.push(callee_output_ty);
+        let fn_sig_binder = Binder::dummy(FnSig {
+            inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output),
+            c_variadic: false,
+            // This does not matter for the ABI.
+            safety: Safety::Safe,
+            abi: callee_abi,
+        });
+        let callee_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?;
+
+        this.check_abi_and_shim_symbol_clash(caller_fn_abi, callee_fn_abi.conv, link_name)?;
+
+        if caller_fn_abi.c_variadic {
+            throw_ub_format!(
+                "ABI mismatch: calling a non-variadic function with a variadic caller-side signature"
+            );
+        }
+
+        if callee_fn_abi.fixed_count != caller_fn_abi.fixed_count {
+            throw_ub_format!(
+                "ABI mismatch: expected {} arguments, found {} arguments ",
+                callee_fn_abi.fixed_count,
+                caller_fn_abi.fixed_count
+            );
+        }
+
+        if callee_fn_abi.can_unwind && !caller_fn_abi.can_unwind {
+            throw_ub_format!(
+                "ABI mismatch: callee may unwind, but caller-side signature prohibits unwinding",
+            );
+        }
+
+        if !this.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? {
+            throw_ub!(AbiMismatchReturn {
+                caller_ty: caller_fn_abi.ret.layout.ty,
+                callee_ty: callee_fn_abi.ret.layout.ty
+            });
+        }
+
+        if let Some(index) = caller_fn_abi
+            .args
+            .iter()
+            .zip(callee_fn_abi.args.iter())
+            .map(|(caller_arg, callee_arg)| this.check_argument_compat(caller_arg, callee_arg))
+            .collect::<InterpResult<'tcx, Vec<bool>>>()?
+            .into_iter()
+            .position(|b| !b)
+        {
+            throw_ub!(AbiMismatchArgument {
+                caller_ty: caller_fn_abi.args[index].layout.ty,
+                callee_ty: callee_fn_abi.args[index].layout.ty
+            });
+        }
+
+        if let Ok(ops) = caller_args.try_into() {
+            return interp_ok(ops);
+        }
+        unreachable!()
+    }
+
     /// Check shim for variadic function.
     /// Returns a tuple that consisting of an array of fixed args, and a slice of varargs.
     fn check_shim_variadic<'a, const N: usize>(
@@ -1187,6 +1259,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         interp_ok(array)
     }
+
+    fn mangle_internal_symbol<'a>(&'a mut self, name: &'static str) -> &'a str
+    where
+        'tcx: 'a,
+    {
+        let this = self.eval_context_mut();
+        let tcx = *this.tcx;
+        this.machine
+            .mangle_internal_symbol_cache
+            .entry(name)
+            .or_insert_with(|| mangle_internal_symbol(tcx, name))
+    }
 }
 
 impl<'tcx> MiriMachine<'tcx> {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 9006190cbee..fb99bdc5176 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -611,6 +611,9 @@ pub struct MiriMachine<'tcx> {
     pub(crate) reject_in_isolation_warned: RefCell<FxHashSet<String>>,
     /// Remembers which int2ptr casts we have already warned about.
     pub(crate) int2ptr_warned: RefCell<FxHashSet<Span>>,
+
+    /// Cache for `mangle_internal_symbol`.
+    pub(crate) mangle_internal_symbol_cache: FxHashMap<&'static str, String>,
 }
 
 impl<'tcx> MiriMachine<'tcx> {
@@ -757,6 +760,7 @@ impl<'tcx> MiriMachine<'tcx> {
             native_call_mem_warned: Cell::new(false),
             reject_in_isolation_warned: Default::default(),
             int2ptr_warned: Default::default(),
+            mangle_internal_symbol_cache: Default::default(),
         }
     }
 
@@ -930,6 +934,7 @@ impl VisitProvenance for MiriMachine<'_> {
             native_call_mem_warned: _,
             reject_in_isolation_warned: _,
             int2ptr_warned: _,
+            mangle_internal_symbol_cache: _,
         } = self;
 
         threads.visit_provenance(visit);
@@ -1540,7 +1545,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     fn before_terminator(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
         ecx.machine.basic_block_count += 1u64; // a u64 that is only incremented by 1 will "never" overflow
         ecx.machine.since_gc += 1;
-        // Possibly report our progress.
+        // Possibly report our progress. This will point at the terminator we are about to execute.
         if let Some(report_progress) = ecx.machine.report_progress {
             if ecx.machine.basic_block_count % u64::from(report_progress) == 0 {
                 ecx.emit_diagnostic(NonHaltingDiagnostic::ProgressReport {
@@ -1559,6 +1564,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         }
 
         // These are our preemption points.
+        // (This will only take effect after the terminator has been executed.)
         ecx.maybe_preempt_active_thread();
 
         // Make sure some time passes.
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 03c6081e992..52c16a0c2e2 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -9,10 +9,9 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::AllocInit;
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{Instance, Ty};
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
-use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::callconv::{Conv, FnAbi};
 
 use self::helpers::{ToHost, ToSoft};
@@ -52,7 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // Some shims forward to other MIR bodies.
         match link_name.as_str() {
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_error_handler") => {
+            name if name == this.mangle_internal_symbol("__rust_alloc_error_handler") => {
                 // Forward to the right symbol that implements this function.
                 let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else {
                     // in real code, this symbol does not exist without an allocator
@@ -60,11 +59,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set"
                     );
                 };
-                let name =
-                    mangle_internal_symbol(*this.tcx, alloc_error_handler_name(handler_kind));
-                let handler = this
-                    .lookup_exported_symbol(Symbol::intern(&name))?
-                    .expect("missing alloc error handler symbol");
+                let name = Symbol::intern(
+                    this.mangle_internal_symbol(alloc_error_handler_name(handler_kind)),
+                );
+                let handler =
+                    this.lookup_exported_symbol(name)?.expect("missing alloc error handler symbol");
                 return interp_ok(Some(handler));
             }
             _ => {}
@@ -138,30 +137,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Find it if it was not cached.
                 let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None;
                 helpers::iter_exported_symbols(tcx, |cnum, def_id| {
+                    let attrs = tcx.codegen_fn_attrs(def_id);
+                    // Skip over imports of items.
                     if tcx.is_foreign_item(def_id) {
-                        // Skip over imports of items
                         return interp_ok(());
                     }
-
-                    let attrs = tcx.codegen_fn_attrs(def_id);
-                    // FIXME use tcx.symbol_name(instance) instead
-                    let symbol_name = if let Some(export_name) = attrs.export_name {
-                        export_name
-                    } else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
-                        || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
+                    // Skip over items without an explicitly defined symbol name.
+                    if !(attrs.export_name.is_some()
+                        || attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
+                        || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL))
                     {
-                        tcx.item_name(def_id)
-                    } else {
-                        // Skip over items without an explicitly defined symbol name.
                         return interp_ok(());
-                    };
-                    let symbol_name =
-                        if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
-                            Symbol::intern(&mangle_internal_symbol(tcx, symbol_name.as_str()))
-                        } else {
-                            symbol_name
-                        };
-                    if symbol_name == link_name {
+                    }
+
+                    let instance = Instance::mono(tcx, def_id);
+                    let symbol_name = tcx.symbol_name(instance).name;
+                    if symbol_name == link_name.as_str() {
                         if let Some((original_instance, original_cnum)) = instance_and_crate {
                             // Make sure we are consistent wrt what is 'first' and 'second'.
                             let original_span = tcx.def_span(original_instance.def_id()).data();
@@ -505,9 +496,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
 
             // Rust allocation
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc")
-                || name == "miri_alloc" =>
-            {
+            name if name == this.mangle_internal_symbol("__rust_alloc") || name == "miri_alloc" => {
                 let default = |ecx: &mut MiriInterpCx<'tcx>| {
                     // Only call `check_shim` when `#[global_allocator]` isn't used. When that
                     // macro is used, we act like no shim exists, so that the exported function can run.
@@ -540,7 +529,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     _ => return this.emulate_allocator(default),
                 }
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_zeroed") => {
+            name if name == this.mangle_internal_symbol("__rust_alloc_zeroed") => {
                 return this.emulate_allocator(|this| {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
@@ -559,7 +548,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.write_pointer(ptr, dest)
                 });
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_dealloc")
+            name if name == this.mangle_internal_symbol("__rust_dealloc")
                 || name == "miri_dealloc" =>
             {
                 let default = |ecx: &mut MiriInterpCx<'tcx>| {
@@ -592,7 +581,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     _ => return this.emulate_allocator(default),
                 }
             }
-            name if name == mangle_internal_symbol(*this.tcx, "__rust_realloc") => {
+            name if name == this.mangle_internal_symbol("__rust_realloc") => {
                 return this.emulate_allocator(|this| {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index fc58d88591f..18af8214876 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -144,7 +144,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Directly return to caller of `try`.
                 StackPopCleanup::Goto {
                     ret: catch_unwind.ret,
-                    unwind: mir::UnwindAction::Continue,
+                    // `catch_fn` must not unwind.
+                    unwind: mir::UnwindAction::Unreachable,
                 },
             )?;
 
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 09757071075..1770b99c0a2 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -1,7 +1,7 @@
 use std::ffi::OsStr;
 use std::str;
 
-use rustc_abi::Size;
+use rustc_abi::{ExternAbi, Size};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::Symbol;
@@ -200,7 +200,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
             "close" => {
-                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.close(fd)?;
                 this.write_scalar(result, dest)?;
             }
diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs
new file mode 100644
index 00000000000..eb8de04dcc4
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.rs
@@ -0,0 +1,21 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int};
+use std::os::unix::ffi::OsStrExt;
+
+extern "C" {
+    fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
+    // correct fd type is i32
+    fn close(fd: u32) -> c_int;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+    } as u32;
+    let _ = unsafe {
+        close(fd);
+        //~^ ERROR: calling a function with argument of type i32 passing data of type u32
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr
new file mode 100644
index 00000000000..90d4ce78ad4
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/input_arg_mismatch.stderr
@@ -0,0 +1,17 @@
+error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32
+  --> tests/fail/shims/input_arg_mismatch.rs:LL:CC
+   |
+LL |         close(fd);
+   |         ^^^^^^^^^ calling a function with argument of type i32 passing data of type u32
+   |
+   = 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
+   = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
+   = help: if you think this code should be accepted anyway, please report an issue with Miri
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/input_arg_mismatch.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/shims/return_type_mismatch.rs b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs
new file mode 100644
index 00000000000..6dbdd3f539b
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.rs
@@ -0,0 +1,21 @@
+//@ignore-target: windows # File handling is not implemented yet
+//@compile-flags: -Zmiri-disable-isolation
+use std::ffi::{CString, OsStr, c_char, c_int, c_short};
+use std::os::unix::ffi::OsStrExt;
+
+extern "C" {
+    fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
+    // correct return type is i32
+    fn close(fd: c_int) -> c_short;
+}
+
+fn main() {
+    let c_path = CString::new(OsStr::new("./text").as_bytes()).expect("CString::new failed");
+    let fd = unsafe {
+        open(c_path.as_ptr(), /* value does not matter */ 0)
+    };
+    let _ = unsafe {
+        close(fd);
+        //~^ ERROR: calling a function with return type i32 passing return place of type i16
+    };
+}
diff --git a/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr
new file mode 100644
index 00000000000..062aa7b4927
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/return_type_mismatch.stderr
@@ -0,0 +1,17 @@
+error: Undefined Behavior: calling a function with return type i32 passing return place of type i16
+  --> tests/fail/shims/return_type_mismatch.rs:LL:CC
+   |
+LL |         close(fd);
+   |         ^^^^^^^^^ calling a function with return type i32 passing return place of type i16
+   |
+   = 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
+   = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets
+   = help: if you think this code should be accepted anyway, please report an issue with Miri
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/return_type_mismatch.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
index 0ca13b5039d..f8f1c554f0d 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
@@ -64,7 +64,7 @@ fn wait_wrong_val() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::EAGAIN);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EAGAIN);
     }
 }
 
@@ -85,7 +85,7 @@ fn wait_timeout() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
     }
 
     assert!((200..1000).contains(&start.elapsed().as_millis()));
@@ -124,7 +124,7 @@ fn wait_absolute_timeout() {
             ),
             -1,
         );
-        assert_eq!(*libc::__errno_location(), libc::ETIMEDOUT);
+        assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
     }
 
     assert!((200..1000).contains(&start.elapsed().as_millis()));
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
index 01433edf9a3..d6072c2569e 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
@@ -56,8 +56,7 @@ fn test_pipe_threaded() {
         assert_eq!(res, 5);
         assert_eq!(buf, "abcde".as_bytes());
     });
-    // FIXME: we should yield here once blocking is implemented.
-    //thread::yield_now();
+    thread::yield_now();
     let data = "abcde".as_bytes().as_ptr();
     let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
     assert_eq!(res, 5);
@@ -65,14 +64,11 @@ fn test_pipe_threaded() {
 
     // Read and write from different direction
     let thread2 = thread::spawn(move || {
-        // FIXME: we should yield here once blocking is implemented.
-        //thread::yield_now();
+        thread::yield_now();
         let data = "12345".as_bytes().as_ptr();
         let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
         assert_eq!(res, 5);
     });
-    // FIXME: we should not yield here once blocking is implemented.
-    thread::yield_now();
     let mut buf: [u8; 5] = [0; 5];
     let res = unsafe { libc::read(fds[0], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) };
     assert_eq!(res, 5);
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index b3b6fe1a5d7..05ac5e82b56 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1281,7 +1281,6 @@ fn test_non_determinism() {
     /// Ensure that the operation is non-deterministic
     #[track_caller]
     fn ensure_nondet<T: PartialEq + std::fmt::Debug>(f: impl Fn() -> T) {
-
         let rounds = 16;
         let first = f();
         for _ in 1..rounds {
diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
index b50bf01453d..1e12259e483 100644
--- a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
+++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs
@@ -17,4 +17,17 @@ impl Bar<'static> for B {
     const STATIC: &str = "";
 }
 
+struct C;
+impl Bar<'_> for C {
+    // make  ^^ not cause
+    const STATIC: &'static str = {
+        struct B;
+        impl Bar<'static> for B {
+            const STATIC: &str = "";
+            //            ^ to emit a future incompat warning
+        }
+        ""
+    };
+}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
index 2c130664e9a..f9b5176d78a 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.rs
@@ -17,4 +17,13 @@ impl Mop {
     //~| ERROR: unconstrained opaque type
 }
 
+fn funky(_: [(); {
+    impl Foo for fn() {
+        type Bar = impl Sized;
+        //~^ ERROR: `impl Trait` in associated types is unstable
+        //~| ERROR: unconstrained opaque type
+    }
+    0
+}]) {}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
index 7dfd79c7286..01d25c16228 100644
--- a/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
+++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_assoc_type.stderr
@@ -18,6 +18,16 @@ LL |     type Bop = impl std::fmt::Debug;
    = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error[E0658]: `impl Trait` in associated types is unstable
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20
+   |
+LL |         type Bar = impl Sized;
+   |                    ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(impl_trait_in_assoc_type)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0658]: inherent associated types are unstable
   --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:14:5
    |
@@ -44,6 +54,14 @@ LL |     type Bop = impl std::fmt::Debug;
    |
    = note: `Bop` must be used in combination with a concrete type within the same impl
 
-error: aborting due to 5 previous errors
+error: unconstrained opaque type
+  --> $DIR/feature-gate-impl_trait_in_assoc_type.rs:22:20
+   |
+LL |         type Bar = impl Sized;
+   |                    ^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
index ec70a20844a..d332fba0623 100644
--- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
+++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs
@@ -1,38 +1,42 @@
-//@ check-pass
-#![feature(type_alias_impl_trait)]
 use std::fmt::Debug;
 
-type Foo = impl Debug;
+type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
 struct Bar(Foo);
-#[define_opaque(Foo)]
+#[define_opaque(Foo)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define() -> Bar {
     Bar(42)
 }
 
-type Foo2 = impl Debug;
+type Foo2 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo2)]
+#[define_opaque(Foo2)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define2() {
     let x = || -> Foo2 { 42 };
 }
 
-type Foo3 = impl Debug;
+type Foo3 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo3)]
+#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define3(x: Foo3) {
     let y: i32 = x;
 }
-#[define_opaque(Foo3)]
+#[define_opaque(Foo3)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define3_1() {
     define3(42)
 }
 
-type Foo4 = impl Debug;
+type Foo4 = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
 
-#[define_opaque(Foo4)]
+#[define_opaque(Foo4)] //~ ERROR use of unstable library feature `type_alias_impl_trait`
 fn define4(_: Foo4) {
     let y: Foo4 = 42;
 }
 
+type Foo5 = [(); {
+    type Foo = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable
+    //~^ ERROR unconstrained opaque type
+    0
+}];
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
new file mode 100644
index 00000000000..bab60eb4293
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
@@ -0,0 +1,111 @@
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:6:3
+   |
+LL | #[define_opaque(Foo)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:13:3
+   |
+LL | #[define_opaque(Foo2)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:20:3
+   |
+LL | #[define_opaque(Foo3)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:24:3
+   |
+LL | #[define_opaque(Foo3)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature `type_alias_impl_trait`: `type_alias_impl_trait` has open design concerns
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:31:3
+   |
+LL | #[define_opaque(Foo4)]
+   |   ^^^^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:3:12
+   |
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:11:13
+   |
+LL | type Foo2 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:18:13
+   |
+LL | type Foo3 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:29:13
+   |
+LL | type Foo4 = impl Debug;
+   |             ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `impl Trait` in type aliases is unstable
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16
+   |
+LL |     type Foo = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+   = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: unconstrained opaque type
+  --> $DIR/feature-gate-type_alias_impl_trait.rs:37:16
+   |
+LL |     type Foo = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: `Foo` must be used in combination with a concrete type within the same crate
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/impl-trait/impl_trait_projections.rs b/tests/ui/impl-trait/impl_trait_projections.rs
index 2c277aee06d..89fe3c1509c 100644
--- a/tests/ui/impl-trait/impl_trait_projections.rs
+++ b/tests/ui/impl-trait/impl_trait_projections.rs
@@ -35,4 +35,9 @@ fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
     panic!()
 }
 
+fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::<impl Sized>] {
+    //~^ ERROR `impl Trait` is not allowed in paths
+    loop {}
+}
+
 fn main() {}
diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr
index 5e0b80fcd59..21f45613938 100644
--- a/tests/ui/impl-trait/impl_trait_projections.stderr
+++ b/tests/ui/impl-trait/impl_trait_projections.stderr
@@ -30,6 +30,14 @@ LL |     -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error: aborting due to 4 previous errors
+error[E0562]: `impl Trait` is not allowed in paths
+  --> $DIR/impl_trait_projections.rs:38:68
+   |
+LL | fn parametrized_value_in_anon_const_is_disallowed() -> [(); None::<impl Sized>] {
+   |                                                                    ^^^^^^^^^^
+   |
+   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs
new file mode 100644
index 00000000000..ab54d5f87ba
--- /dev/null
+++ b/tests/ui/impl-trait/inside-item-nested-in-anon-const.rs
@@ -0,0 +1,25 @@
+// Ensure we don't misclassify `impl Trait` as TAIT/ATPIT if located inside an anon const in a
+// type alias/assoc type.
+// issue: <https://github.com/rust-lang/rust/issues/139055>
+//@ check-pass
+#![forbid(unstable_features)]
+
+struct Girder<const N: usize>;
+
+type Alias = Girder<{
+    fn pass(input: impl Sized) -> impl Sized { input }
+    0
+}>;
+
+trait Trait {
+    type Assoc;
+}
+
+impl Trait for () {
+    type Assoc = [(); {
+        fn pass(input: impl Sized) -> impl Sized { input }
+        0
+    }];
+}
+
+fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index 91b487bb96d..217da993538 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -254,6 +254,16 @@ trigger_files = [
     "compiler/rustc_attr_data_structures",
 ]
 
+[autolabel."F-autodiff"]
+trigger_files = [
+    "src/tools/enzyme",
+    "src/doc/unstable-book/src/compiler-flags/autodiff.md",
+    "compiler/rustc_ast/src/expand/autodiff_attrs.rs",
+    "compiler/rustc_monomorphize/src/partitioning/autodiff.rs",
+    "compiler/rustc_codegen_llvm/src/builder/autodiff.rs",
+    "compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs",
+]
+
 [autolabel."T-rustdoc-frontend"]
 trigger_labels = [
     "A-rustdoc-search",
@@ -1092,6 +1102,23 @@ cc = ["@jdonszelmann"]
 [mentions."compiler/rustc_attr_data_structures"]
 cc = ["@jdonszelmann"]
 
+[mentions."src/tools/enzyme"]
+cc = ["@ZuseZ4"]
+[mentions."src/doc/unstable-book/src/compiler-flags/autodiff.md"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_ast/src/expand/autodiff_attrs.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_ast/src/expand/typetree.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_builtin_macros/src/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_monomorphize/src/partitioning/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_codegen_llvm/src/builder/autodiff.rs"]
+cc = ["@ZuseZ4"]
+[mentions."compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs"]
+cc = ["@ZuseZ4"]
+
 [assign]
 warn_non_default_branch.enable = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"