about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock151
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs5
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs89
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs22
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs9
-rw-r--r--compiler/rustc_lint/src/unused.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs12
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs24
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs59
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs21
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs47
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs8
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs14
-rw-r--r--compiler/rustc_type_ir/src/relate/solver_relating.rs12
-rw-r--r--compiler/rustc_type_ir/src/search_graph/global_cache.rs36
-rw-r--r--library/core/src/intrinsics/simd.rs42
-rw-r--r--library/std/src/sys/fs/windows/remove_dir_all.rs19
-rw-r--r--library/std/src/sys/pal/windows/api.rs73
-rw-r--r--library/std/src/sys/pal/windows/c.rs7
-rw-r--r--library/std/src/sys/pal/windows/pipe.rs13
-rw-r--r--library/stdarch/crates/intrinsic-test/README.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/ui.md2
-rw-r--r--src/doc/unstable-book/src/language-features/type-alias-impl-trait.md2
-rw-r--r--src/tools/miri/Cargo.lock199
-rw-r--r--src/tools/miri/Cargo.toml6
-rw-r--r--src/tools/miri/README.md3
-rw-r--r--src/tools/miri/miri-script/src/commands.rs83
-rw-r--r--src/tools/miri/miri-script/src/coverage.rs7
-rw-r--r--src/tools/miri/miri-script/src/main.rs38
-rw-r--r--src/tools/miri/miri-script/src/util.rs90
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc/isolated_alloc.rs177
-rw-r--r--src/tools/miri/src/alloc_addresses/reuse_pool.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs15
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs6
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs182
-rw-r--r--src/tools/miri/src/diagnostics.rs60
-rw-r--r--src/tools/miri/src/eval.rs3
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs102
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs2
-rw-r--r--src/tools/miri/src/lib.rs6
-rw-r--r--src/tools/miri/src/machine.rs4
-rw-r--r--src/tools/miri/src/shims/mod.rs2
-rw-r--r--src/tools/miri/src/shims/native_lib/mod.rs (renamed from src/tools/miri/src/shims/native_lib.rs)171
-rw-r--r--src/tools/miri/src/shims/native_lib/trace/child.rs251
-rw-r--r--src/tools/miri/src/shims/native_lib/trace/messages.rs80
-rw-r--r--src/tools/miri/src/shims/native_lib/trace/mod.rs8
-rw-r--r--src/tools/miri/src/shims/native_lib/trace/parent.rs660
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs3
-rw-r--r--src/tools/miri/src/shims/unix/linux/mem.rs3
-rw-r--r--src/tools/miri/src/shims/unix/mem.rs3
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs2
-rw-r--r--src/tools/miri/src/shims/unix/thread.rs14
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs3
-rw-r--r--src/tools/miri/src/shims/windows/thread.rs13
-rw-r--r--src/tools/miri/tests/pass/float.rs25
-rw-r--r--src/tools/miri/tests/pass/float_nan.rs26
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs8
-rw-r--r--src/tools/rust-installer/README.md2
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--tests/crashes/132882.rs13
-rw-r--r--tests/ui/allocator/empty-alloc-nonnull-guarantee.rs (renamed from tests/ui/empty-allocation-non-null.rs)4
-rw-r--r--tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs21
-rw-r--r--tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr (renamed from tests/ui/impl-unused-rps-in-assoc-type.stderr)2
-rw-r--r--tests/ui/attributes/inline-attribute-enum-variant-error.rs (renamed from tests/ui/inline-disallow-on-variant.rs)2
-rw-r--r--tests/ui/attributes/inline-attribute-enum-variant-error.stderr (renamed from tests/ui/inline-disallow-on-variant.stderr)2
-rw-r--r--tests/ui/attributes/inline-main.rs6
-rw-r--r--tests/ui/attributes/inner-attrs-impl-cfg.rs36
-rw-r--r--tests/ui/codegen/maximal-hir-to-mir-coverage-flag.rs12
-rw-r--r--tests/ui/compiletest-self-test/ui-test-missing-annotations-detection.rs9
-rw-r--r--tests/ui/derives/derive-Debug-enum-variants.rs30
-rw-r--r--tests/ui/diverging-fn-tail-35849.rs8
-rw-r--r--tests/ui/early-ret-binop-add.rs10
-rw-r--r--tests/ui/elide-errors-on-mismatched-tuple.rs18
-rw-r--r--tests/ui/elided-test.rs5
-rw-r--r--tests/ui/elided-test.stderr9
-rw-r--r--tests/ui/else-if.rs20
-rw-r--r--tests/ui/expr/early-return-in-binop.rs19
-rw-r--r--tests/ui/fmt/debug-single-call.rs (renamed from tests/ui/logging-only-prints-once.rs)7
-rw-r--r--tests/ui/generics/unconstrained-type-params-inherent-impl.rs32
-rw-r--r--tests/ui/generics/unconstrained-type-params-inherent-impl.stderr (renamed from tests/ui/impl-unused-tps-inherent.stderr)8
-rw-r--r--tests/ui/impl-unused-rps-in-assoc-type.rs18
-rw-r--r--tests/ui/impl-unused-tps-inherent.rs25
-rw-r--r--tests/ui/implicit-method-bind.rs3
-rw-r--r--tests/ui/implicit-method-bind.stderr14
-rw-r--r--tests/ui/imports/duplicate-use-bindings.rs (renamed from tests/ui/double-type-import.rs)2
-rw-r--r--tests/ui/imports/duplicate-use-bindings.stderr (renamed from tests/ui/double-type-import.stderr)2
-rw-r--r--tests/ui/indexing/indexing-integral-types.rs (renamed from tests/ui/integral-indexing.rs)12
-rw-r--r--tests/ui/indexing/indexing-integral-types.stderr (renamed from tests/ui/integral-indexing.stderr)16
-rw-r--r--tests/ui/inlined-main.rs4
-rw-r--r--tests/ui/inner-attrs-on-impl.rs24
-rw-r--r--tests/ui/inner-module.rs10
-rw-r--r--tests/ui/inner-static-type-parameter.rs11
-rw-r--r--tests/ui/linkage-attr/link-section-placement.rs (renamed from tests/ui/link-section.rs)3
-rw-r--r--tests/ui/lint/missing-debug-implementations-lint.rs (renamed from tests/ui/missing_debug_impls.rs)8
-rw-r--r--tests/ui/lint/missing-debug-implementations-lint.stderr (renamed from tests/ui/missing_debug_impls.stderr)6
-rw-r--r--tests/ui/lint/unused/must-use-macros.fixed60
-rw-r--r--tests/ui/lint/unused/must-use-macros.rs60
-rw-r--r--tests/ui/lint/unused/must-use-macros.stderr48
-rw-r--r--tests/ui/log-err-phi.rs7
-rw-r--r--tests/ui/log-knows-the-names-of-variants.rs21
-rw-r--r--tests/ui/loud_ui.rs6
-rw-r--r--tests/ui/macros/must-use-in-macro-55516.stderr5
-rw-r--r--tests/ui/maximal_mir_to_hir_coverage.rs10
-rw-r--r--tests/ui/maybe-bounds.rs9
-rw-r--r--tests/ui/method-output-diff-issue-127263.rs8
-rw-r--r--tests/ui/methods/method-missing-call.rs30
-rw-r--r--tests/ui/methods/method-missing-call.stderr25
-rw-r--r--tests/ui/methods/method-value-without-call.rs33
-rw-r--r--tests/ui/methods/method-value-without-call.stderr36
-rw-r--r--tests/ui/mismatched_types/elide-on-tuple-mismatch.rs25
-rw-r--r--tests/ui/mismatched_types/elide-on-tuple-mismatch.stderr (renamed from tests/ui/elide-errors-on-mismatched-tuple.stderr)4
-rw-r--r--tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.rs16
-rw-r--r--tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.stderr (renamed from tests/ui/method-output-diff-issue-127263.stderr)4
-rw-r--r--tests/ui/mismatched_types/int-float-type-mismatch.rs (renamed from tests/ui/integral-variable-unification-error.rs)3
-rw-r--r--tests/ui/mismatched_types/int-float-type-mismatch.stderr (renamed from tests/ui/integral-variable-unification-error.stderr)2
-rw-r--r--tests/ui/mod-subitem-as-enum-variant.rs9
-rw-r--r--tests/ui/modules/nested-modules-basic.rs19
-rw-r--r--tests/ui/parser/reference-whitespace-parsing.rs (renamed from tests/ui/double-ref.rs)2
-rw-r--r--tests/ui/resolve/struct-function-same-name.rs (renamed from tests/ui/max-min-classes.rs)4
-rw-r--r--tests/ui/resolve/type-param-local-var-shadowing.rs (renamed from tests/ui/lexical-scoping.rs)9
-rw-r--r--tests/ui/simd/intrinsic/float-math-pass.rs3
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.stderr74
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-pass.rs74
-rw-r--r--tests/ui/statics/static-generic-param-soundness.rs20
-rw-r--r--tests/ui/statics/static-generic-param-soundness.stderr (renamed from tests/ui/inner-static-type-parameter.stderr)6
-rw-r--r--tests/ui/test-attrs/test-function-elided-no-main.rs8
-rw-r--r--tests/ui/test-attrs/test-function-elided-no-main.stderr9
-rw-r--r--tests/ui/traits/constrained-type-params-trait-impl.rs (renamed from tests/ui/impl-unused-tps.rs)28
-rw-r--r--tests/ui/traits/constrained-type-params-trait-impl.stderr (renamed from tests/ui/impl-unused-tps.stderr)18
-rw-r--r--tests/ui/traits/dispatch-from-dyn-invalid-impls.rs (renamed from tests/ui/invalid_dispatch_from_dyn_impls.rs)48
-rw-r--r--tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr (renamed from tests/ui/invalid_dispatch_from_dyn_impls.stderr)30
-rw-r--r--tests/ui/traits/encoder-trait-bounds-regression.rs (renamed from tests/ui/issue-11881.rs)17
-rw-r--r--tests/ui/traits/eval-caching-error-region.rs23
-rw-r--r--tests/ui/traits/eval-caching-error-region.stderr33
-rw-r--r--tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs18
-rw-r--r--tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr (renamed from tests/ui/maybe-bounds.stderr)6
-rw-r--r--tests/ui/transmute/diverging-fn-transmute.rs10
-rw-r--r--tests/ui/transmute/diverging-fn-transmute.stderr (renamed from tests/ui/diverging-fn-tail-35849.stderr)2
-rw-r--r--tests/ui/type-alias-enum-variants/module-type-args-error.rs16
-rw-r--r--tests/ui/type-alias-enum-variants/module-type-args-error.stderr (renamed from tests/ui/mod-subitem-as-enum-variant.stderr)2
149 files changed, 3301 insertions, 1020 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e1cf17e2c01..110d17142bb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -367,6 +367,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "capstone"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "015ef5d5ca1743e3f94af9509ba6bd2886523cfee46e48d15c2ef5216fd4ac9a"
+dependencies = [
+ "capstone-sys",
+ "libc",
+]
+
+[[package]]
+name = "capstone-sys"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2267cb8d16a1e4197863ec4284ffd1aec26fe7e57c58af46b02590a0235809a0"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
 name = "cargo-miri"
 version = "0.1.0"
 dependencies = [
@@ -738,7 +758,7 @@ dependencies = [
  "tracing-subscriber",
  "unified-diff",
  "walkdir",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -1592,7 +1612,7 @@ dependencies = [
  "js-sys",
  "log",
  "wasm-bindgen",
- "windows-core",
+ "windows-core 0.61.2",
 ]
 
 [[package]]
@@ -1917,6 +1937,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "ipc-channel"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fb8251fb7bcd9ccd3725ed8deae9fe7db8e586495c9eb5b0c52e6233e5e75ea"
+dependencies = [
+ "bincode",
+ "crossbeam-channel",
+ "fnv",
+ "lazy_static",
+ "libc",
+ "mio",
+ "rand 0.8.5",
+ "serde",
+ "tempfile",
+ "uuid",
+ "windows 0.58.0",
+]
+
+[[package]]
 name = "is_terminal_polyfill"
 version = "1.70.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2302,6 +2341,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "mio"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+dependencies = [
+ "libc",
+ "log",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
 name = "miow"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2316,18 +2367,22 @@ version = "0.1.0"
 dependencies = [
  "aes",
  "bitflags",
+ "capstone",
  "chrono",
  "chrono-tz",
  "colored",
  "directories",
  "getrandom 0.3.3",
+ "ipc-channel",
  "libc",
  "libffi",
  "libloading",
  "measureme",
+ "nix",
  "rand 0.9.1",
  "regex",
  "rustc_version",
+ "serde",
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
@@ -3519,7 +3574,7 @@ dependencies = [
  "thorin-dwp",
  "tracing",
  "wasm-encoder 0.219.2",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -3578,7 +3633,7 @@ dependencies = [
  "tempfile",
  "thin-vec",
  "tracing",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -3641,7 +3696,7 @@ dependencies = [
  "shlex",
  "stable_mir",
  "tracing",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -3696,7 +3751,7 @@ dependencies = [
  "termcolor",
  "termize",
  "tracing",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -4457,7 +4512,7 @@ dependencies = [
  "rustc_target",
  "termize",
  "tracing",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -5142,7 +5197,7 @@ dependencies = [
  "libc",
  "objc2-core-foundation",
  "objc2-io-kit",
- "windows",
+ "windows 0.61.3",
 ]
 
 [[package]]
@@ -6036,12 +6091,22 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "windows"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
+dependencies = [
+ "windows-core 0.58.0",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows"
 version = "0.61.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
 dependencies = [
  "windows-collections",
- "windows-core",
+ "windows-core 0.61.2",
  "windows-future",
  "windows-link",
  "windows-numerics",
@@ -6064,7 +6129,20 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
 dependencies = [
- "windows-core",
+ "windows-core 0.61.2",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
+dependencies = [
+ "windows-implement 0.58.0",
+ "windows-interface 0.58.0",
+ "windows-result 0.2.0",
+ "windows-strings 0.1.0",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -6073,11 +6151,11 @@ version = "0.61.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
 dependencies = [
- "windows-implement",
- "windows-interface",
+ "windows-implement 0.60.0",
+ "windows-interface 0.59.1",
  "windows-link",
- "windows-result",
- "windows-strings",
+ "windows-result 0.3.4",
+ "windows-strings 0.4.2",
 ]
 
 [[package]]
@@ -6086,13 +6164,24 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
 dependencies = [
- "windows-core",
+ "windows-core 0.61.2",
  "windows-link",
  "windows-threading",
 ]
 
 [[package]]
 name = "windows-implement"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.103",
+]
+
+[[package]]
+name = "windows-implement"
 version = "0.60.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
@@ -6104,6 +6193,17 @@ dependencies = [
 
 [[package]]
 name = "windows-interface"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.103",
+]
+
+[[package]]
+name = "windows-interface"
 version = "0.59.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
@@ -6125,12 +6225,21 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
 dependencies = [
- "windows-core",
+ "windows-core 0.61.2",
  "windows-link",
 ]
 
 [[package]]
 name = "windows-result"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-result"
 version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
@@ -6140,6 +6249,16 @@ dependencies = [
 
 [[package]]
 name = "windows-strings"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
+dependencies = [
+ "windows-result 0.2.0",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-strings"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 68ff0b622c8..6281089ee24 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -496,7 +496,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
         | sym::simd_flog
         | sym::simd_flog10
         | sym::simd_flog2
-        | sym::simd_round => {
+        | sym::simd_round
+        | sym::simd_round_ties_even => {
             intrinsic_args!(fx, args => (a); intrinsic);
 
             if !a.layout().ty.is_simd() {
@@ -527,6 +528,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                     (sym::simd_flog2, types::F64) => "log2",
                     (sym::simd_round, types::F32) => "roundf",
                     (sym::simd_round, types::F64) => "round",
+                    (sym::simd_round_ties_even, types::F32) => "rintf",
+                    (sym::simd_round_ties_even, types::F64) => "rint",
                     _ => unreachable!("{:?}", intrinsic),
                 };
                 fx.lib_call(
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index ac8b7f4ea48..2e508813fc3 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -780,6 +780,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
             sym::simd_fsin => "sin",
             sym::simd_fsqrt => "sqrt",
             sym::simd_round => "round",
+            sym::simd_round_ties_even => "rint",
             sym::simd_trunc => "trunc",
             _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
         };
@@ -827,6 +828,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
             | sym::simd_fsin
             | sym::simd_fsqrt
             | sym::simd_round
+            | sym::simd_round_ties_even
             | sym::simd_trunc
     ) {
         return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index f7f062849a8..9930eae3fe7 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1537,6 +1537,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             sym::simd_fsin => "llvm.sin",
             sym::simd_fsqrt => "llvm.sqrt",
             sym::simd_round => "llvm.round",
+            sym::simd_round_ties_even => "llvm.rint",
             sym::simd_trunc => "llvm.trunc",
             _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
         };
@@ -1563,6 +1564,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             | sym::simd_fsqrt
             | sym::simd_relaxed_fma
             | sym::simd_round
+            | sym::simd_round_ties_even
             | sym::simd_trunc
     ) {
         return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
@@ -2309,7 +2311,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     // Unary integer intrinsics
     if matches!(
         name,
-        sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctlz | sym::simd_ctpop | sym::simd_cttz
+        sym::simd_bswap
+            | sym::simd_bitreverse
+            | sym::simd_ctlz
+            | sym::simd_ctpop
+            | sym::simd_cttz
+            | sym::simd_funnel_shl
+            | sym::simd_funnel_shr
     ) {
         let vec_ty = bx.cx.type_vector(
             match *in_elem.kind() {
@@ -2330,6 +2338,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             sym::simd_ctlz => "llvm.ctlz",
             sym::simd_ctpop => "llvm.ctpop",
             sym::simd_cttz => "llvm.cttz",
+            sym::simd_funnel_shl => "llvm.fshl",
+            sym::simd_funnel_shr => "llvm.fshr",
             _ => unreachable!(),
         };
         let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits();
@@ -2350,6 +2360,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
                 // simple unary argument cases
                 Ok(bx.call_intrinsic(llvm_intrinsic, &[vec_ty], &[args[0].immediate()]))
             }
+            sym::simd_funnel_shl | sym::simd_funnel_shr => Ok(bx.call_intrinsic(
+                llvm_intrinsic,
+                &[vec_ty],
+                &[args[0].immediate(), args[1].immediate(), args[2].immediate()],
+            )),
             _ => unreachable!(),
         };
     }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 060fc51b7bd..cebf7d1b532 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -594,8 +594,9 @@ pub(crate) fn check_intrinsic_type(
         | sym::simd_ceil
         | sym::simd_floor
         | sym::simd_round
+        | sym::simd_round_ties_even
         | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
-        sym::simd_fma | sym::simd_relaxed_fma => {
+        sym::simd_fma | sym::simd_relaxed_fma | sym::simd_funnel_shl | sym::simd_funnel_shr => {
             (1, 0, vec![param(0), param(0), param(0)], param(0))
         }
         sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 6fa473d177d..57d3c5da873 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -278,8 +278,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     /// fall back to subtyping (`unify_and`).
     fn coerce_from_inference_variable(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
         debug!("coerce_from_inference_variable(a={:?}, b={:?})", a, b);
-        assert!(a.is_ty_var() && self.shallow_resolve(a) == a);
-        assert!(self.shallow_resolve(b) == b);
+        debug_assert!(a.is_ty_var() && self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
 
         if b.is_ty_var() {
             // Two unresolved type variables: create a `Coerce` predicate.
@@ -323,6 +323,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         mutbl_b: hir::Mutability,
     ) -> CoerceResult<'tcx> {
         debug!("coerce_borrowed_pointer(a={:?}, b={:?})", a, b);
+        debug_assert!(self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
 
         // If we have a parameter of type `&M T_a` and the value
         // provided is `expr`, we will be adding an implicit borrow,
@@ -514,10 +516,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     ///
     /// [unsized coercion](https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions)
     #[instrument(skip(self), level = "debug")]
-    fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceResult<'tcx> {
-        source = self.shallow_resolve(source);
-        target = self.shallow_resolve(target);
+    fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tcx> {
         debug!(?source, ?target);
+        debug_assert!(self.shallow_resolve(source) == source);
+        debug_assert!(self.shallow_resolve(target) == target);
 
         // We don't apply any coercions incase either the source or target
         // aren't sufficiently well known but tend to instead just equate
@@ -531,6 +533,54 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             return Err(TypeError::Mismatch);
         }
 
+        // This is an optimization because coercion is one of the most common
+        // operations that we do in typeck, since it happens at every assignment
+        // and call arg (among other positions).
+        //
+        // These targets are known to never be RHS in `LHS: CoerceUnsized<RHS>`.
+        // That's because these are built-in types for which a core-provided impl
+        // doesn't exist, and for which a user-written impl is invalid.
+        //
+        // This is technically incomplete when users write impossible bounds like
+        // `where T: CoerceUnsized<usize>`, for example, but that trait is unstable
+        // and coercion is allowed to be incomplete. The only case where this matters
+        // is impossible bounds.
+        //
+        // Note that some of these types implement `LHS: Unsize<RHS>`, but they
+        // do not implement *`CoerceUnsized`* which is the root obligation of the
+        // check below.
+        match target.kind() {
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Slice(_)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_, _)
+            | ty::Dynamic(_, _, _)
+            | ty::Closure(_, _)
+            | ty::CoroutineClosure(_, _)
+            | ty::Coroutine(_, _)
+            | ty::CoroutineWitness(_, _)
+            | ty::Never
+            | ty::Tuple(_) => return Err(TypeError::Mismatch),
+            _ => {}
+        }
+        // Additionally, we ignore `&str -> &str` coercions, which happen very
+        // commonly since strings are one of the most used argument types in Rust,
+        // we do coercions when type checking call expressions.
+        if let ty::Ref(_, source_pointee, ty::Mutability::Not) = *source.kind()
+            && source_pointee.is_str()
+            && let ty::Ref(_, target_pointee, ty::Mutability::Not) = *target.kind()
+            && target_pointee.is_str()
+        {
+            return Err(TypeError::Mismatch);
+        }
+
         let traits =
             (self.tcx.lang_items().unsize_trait(), self.tcx.lang_items().coerce_unsized_trait());
         let (Some(unsize_did), Some(coerce_unsized_did)) = traits else {
@@ -800,6 +850,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     /// - `Pin<Box<T>>` as `Pin<&mut T>`
     #[instrument(skip(self), level = "trace")]
     fn coerce_pin_ref(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
+        debug_assert!(self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
+
         // We need to make sure the two types are compatible for coercion.
         // Then we will build a ReborrowPin adjustment and return that as an InferOk.
 
@@ -848,6 +901,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         b: Ty<'tcx>,
         adjustment: Option<Adjust>,
     ) -> CoerceResult<'tcx> {
+        debug_assert!(self.shallow_resolve(b) == b);
+
         self.commit_if_ok(|snapshot| {
             let outer_universe = self.infcx.universe();
 
@@ -888,24 +943,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         fn_ty_a: ty::PolyFnSig<'tcx>,
         b: Ty<'tcx>,
     ) -> CoerceResult<'tcx> {
-        //! Attempts to coerce from the type of a Rust function item
-        //! into a closure or a `proc`.
-        //!
-
-        let b = self.shallow_resolve(b);
         debug!(?fn_ty_a, ?b, "coerce_from_fn_pointer");
+        debug_assert!(self.shallow_resolve(b) == b);
 
         self.coerce_from_safe_fn(fn_ty_a, b, None)
     }
 
     fn coerce_from_fn_item(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
-        //! Attempts to coerce from the type of a Rust function item
-        //! into a closure or a `proc`.
+        debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
+        debug_assert!(self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
 
-        let b = self.shallow_resolve(b);
         let InferOk { value: b, mut obligations } =
             self.at(&self.cause, self.param_env).normalize(b);
-        debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
 
         match b.kind() {
             ty::FnPtr(_, b_hdr) => {
@@ -955,6 +1005,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         }
     }
 
+    /// Attempts to coerce from the type of a non-capturing closure
+    /// into a function pointer.
     fn coerce_closure_to_fn(
         &self,
         a: Ty<'tcx>,
@@ -962,11 +1014,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         args_a: GenericArgsRef<'tcx>,
         b: Ty<'tcx>,
     ) -> CoerceResult<'tcx> {
-        //! Attempts to coerce from the type of a non-capturing closure
-        //! into a function pointer.
-        //!
-
-        let b = self.shallow_resolve(b);
+        debug_assert!(self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
 
         match b.kind() {
             // At this point we haven't done capture analysis, which means
@@ -1010,6 +1059,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         mutbl_b: hir::Mutability,
     ) -> CoerceResult<'tcx> {
         debug!("coerce_raw_ptr(a={:?}, b={:?})", a, b);
+        debug_assert!(self.shallow_resolve(a) == a);
+        debug_assert!(self.shallow_resolve(b) == b);
 
         let (is_ref, mt_a) = match *a.kind() {
             ty::Ref(_, ty, mutbl) => (true, ty::TypeAndMut { ty, mutbl }),
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index d0a48872f75..df1ee0e79c2 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3055,7 +3055,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn note_unmet_impls_on_type(
         &self,
         err: &mut Diag<'_>,
-        errors: Vec<FulfillmentError<'tcx>>,
+        errors: &[FulfillmentError<'tcx>],
         suggest_derive: bool,
     ) {
         let preds: Vec<_> = errors
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index b9d24506986..87a7cd62ae5 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -322,7 +322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             lhs_expr.span,
                             format!("cannot use `{}` on type `{}`", s, lhs_ty_str),
                         );
-                        self.note_unmet_impls_on_type(&mut err, errors, false);
+                        self.note_unmet_impls_on_type(&mut err, &errors, false);
                         (err, None)
                     }
                     Op::BinOp(bin_op) => {
@@ -382,7 +382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             err.span_label(rhs_expr.span, rhs_ty_str);
                         }
                         let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
-                        self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
+                        self.note_unmet_impls_on_type(&mut err, &errors, suggest_derive);
                         (err, output_def_id)
                     }
                 };
@@ -582,22 +582,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // concatenation (e.g., "Hello " + "World!"). This means
                         // we don't want the note in the else clause to be emitted
                     } else if lhs_ty.has_non_region_param() {
-                        // Look for a TraitPredicate in the Fulfillment errors,
-                        // and use it to generate a suggestion.
-                        //
-                        // Note that lookup_op_method must be called again but
-                        // with a specific rhs_ty instead of a placeholder so
-                        // the resulting predicate generates a more specific
-                        // suggestion for the user.
-                        let errors = self
-                            .lookup_op_method(
-                                (lhs_expr, lhs_ty),
-                                Some((rhs_expr, rhs_ty)),
-                                lang_item_for_binop(self.tcx, op),
-                                op.span(),
-                                expected,
-                            )
-                            .unwrap_err();
                         if !errors.is_empty() {
                             for error in errors {
                                 if let Some(trait_pred) =
@@ -946,7 +930,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             ty::Str | ty::Never | ty::Char | ty::Tuple(_) | ty::Array(_, _) => {}
                             ty::Ref(_, lty, _) if *lty.kind() == ty::Str => {}
                             _ => {
-                                self.note_unmet_impls_on_type(&mut err, errors, true);
+                                self.note_unmet_impls_on_type(&mut err, &errors, true);
                             }
                         }
                     }
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index cae674165f0..ddc0b116806 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -110,17 +110,16 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         match r.kind() {
-            ty::ReBound(..) => {
-                // leave bound regions alone
-                r
-            }
+            // Leave bound regions alone, since they affect selection via the leak check.
+            ty::ReBound(..) => r,
+            // Leave error regions alone, since they affect selection b/c of incompleteness.
+            ty::ReError(_) => r,
 
             ty::ReEarlyParam(..)
             | ty::ReLateParam(_)
             | ty::ReVar(_)
             | ty::RePlaceholder(..)
             | ty::ReStatic
-            | ty::ReError(_)
             | ty::ReErased => self.cx().lifetimes.re_erased,
         }
     }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index a868c887493..a206f71e153 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -183,6 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
         let mut op_warned = false;
 
         if let Some(must_use_op) = must_use_op {
+            let span = expr.span.find_oldest_ancestor_in_same_ctxt();
             cx.emit_span_lint(
                 UNUSED_MUST_USE,
                 expr.span,
@@ -191,11 +192,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     label: expr.span,
                     suggestion: if expr_is_from_block {
                         UnusedOpSuggestion::BlockTailExpr {
-                            before_span: expr.span.shrink_to_lo(),
-                            after_span: expr.span.shrink_to_hi(),
+                            before_span: span.shrink_to_lo(),
+                            after_span: span.shrink_to_hi(),
                         }
                     } else {
-                        UnusedOpSuggestion::NormalExpr { span: expr.span.shrink_to_lo() }
+                        UnusedOpSuggestion::NormalExpr { span: span.shrink_to_lo() }
                     },
                 },
             );
@@ -508,9 +509,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     );
                 }
                 MustUsePath::Def(span, def_id, reason) => {
+                    let span = span.find_oldest_ancestor_in_same_ctxt();
                     cx.emit_span_lint(
                         UNUSED_MUST_USE,
-                        *span,
+                        span,
                         UnusedDef {
                             pre: descr_pre,
                             post: descr_post,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index a300558c0c9..c281ef216c7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -383,10 +383,10 @@ where
 
         let mut candidates = vec![];
 
-        if let TypingMode::Coherence = self.typing_mode() {
-            if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
-                return vec![candidate];
-            }
+        if let TypingMode::Coherence = self.typing_mode()
+            && let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal)
+        {
+            return vec![candidate];
         }
 
         self.assemble_alias_bound_candidates(goal, &mut candidates);
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 5b6f9785272..73bb1508de9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -997,12 +997,12 @@ where
     }
 
     fn try_fold_ty(&mut self, ty: I::Ty) -> Result<I::Ty, Ambiguous> {
-        if let ty::Alias(ty::Projection, alias_ty) = ty.kind() {
-            if let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())? {
-                return Ok(term.expect_ty());
-            }
+        if let ty::Alias(ty::Projection, alias_ty) = ty.kind()
+            && let Some(term) = self.try_eagerly_replace_alias(alias_ty.into())?
+        {
+            Ok(term.expect_ty())
+        } else {
+            ty.try_super_fold_with(self)
         }
-
-        ty.try_super_fold_with(self)
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 0547eb77f8d..42264f58bcd 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -42,20 +42,18 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        if let Some(host_clause) = assumption.as_host_effect_clause() {
-            if host_clause.def_id() == goal.predicate.def_id()
-                && host_clause.constness().satisfies(goal.predicate.constness)
-            {
-                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
-                    goal.predicate.trait_ref.args,
-                    host_clause.skip_binder().trait_ref.args,
-                ) {
-                    return Ok(());
-                }
-            }
+        if let Some(host_clause) = assumption.as_host_effect_clause()
+            && host_clause.def_id() == goal.predicate.def_id()
+            && host_clause.constness().satisfies(goal.predicate.constness)
+            && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                goal.predicate.trait_ref.args,
+                host_clause.skip_binder().trait_ref.args,
+            )
+        {
+            Ok(())
+        } else {
+            Err(NoSolution)
         }
-
-        Err(NoSolution)
     }
 
     fn match_assumption(
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index dd9ccadf6cf..b42587618b5 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -429,22 +429,21 @@ where
         // If we have run this goal before, and it was stalled, check that any of the goal's
         // args have changed. Otherwise, we don't need to re-run the goal because it'll remain
         // stalled, since it'll canonicalize the same way and evaluation is pure.
-        if let Some(stalled_on) = stalled_on {
-            if !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
-                && !self
-                    .delegate
-                    .opaque_types_storage_num_entries()
-                    .needs_reevaluation(stalled_on.num_opaques)
-            {
-                return Ok((
-                    NestedNormalizationGoals::empty(),
-                    GoalEvaluation {
-                        certainty: Certainty::Maybe(stalled_on.stalled_cause),
-                        has_changed: HasChanged::No,
-                        stalled_on: Some(stalled_on),
-                    },
-                ));
-            }
+        if let Some(stalled_on) = stalled_on
+            && !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
+            && !self
+                .delegate
+                .opaque_types_storage_num_entries()
+                .needs_reevaluation(stalled_on.num_opaques)
+        {
+            return Ok((
+                NestedNormalizationGoals::empty(),
+                GoalEvaluation {
+                    certainty: Certainty::Maybe(stalled_on.stalled_cause),
+                    has_changed: HasChanged::No,
+                    stalled_on: Some(stalled_on),
+                },
+            ));
         }
 
         let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
@@ -833,14 +832,11 @@ where
 
                 match t.kind() {
                     ty::Infer(ty::TyVar(vid)) => {
-                        if let ty::TermKind::Ty(term) = self.term.kind() {
-                            if let ty::Infer(ty::TyVar(term_vid)) = term.kind() {
-                                if self.delegate.root_ty_var(vid)
-                                    == self.delegate.root_ty_var(term_vid)
-                                {
-                                    return ControlFlow::Break(());
-                                }
-                            }
+                        if let ty::TermKind::Ty(term) = self.term.kind()
+                            && let ty::Infer(ty::TyVar(term_vid)) = term.kind()
+                            && self.delegate.root_ty_var(vid) == self.delegate.root_ty_var(term_vid)
+                        {
+                            return ControlFlow::Break(());
                         }
 
                         self.check_nameable(self.delegate.universe_of_ty(vid).unwrap())?;
@@ -860,15 +856,12 @@ where
             fn visit_const(&mut self, c: I::Const) -> Self::Result {
                 match c.kind() {
                     ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
-                        if let ty::TermKind::Const(term) = self.term.kind() {
-                            if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
-                            {
-                                if self.delegate.root_const_var(vid)
-                                    == self.delegate.root_const_var(term_vid)
-                                {
-                                    return ControlFlow::Break(());
-                                }
-                            }
+                        if let ty::TermKind::Const(term) = self.term.kind()
+                            && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
+                            && self.delegate.root_const_var(vid)
+                                == self.delegate.root_const_var(term_vid)
+                        {
+                            return ControlFlow::Break(());
                         }
 
                         self.check_nameable(self.delegate.universe_of_ct(vid).unwrap())
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index d51c87fe68e..edb354b4a84 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -112,18 +112,17 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        if let Some(projection_pred) = assumption.as_projection_clause() {
-            if projection_pred.item_def_id() == goal.predicate.def_id() {
-                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
-                    goal.predicate.alias.args,
-                    projection_pred.skip_binder().projection_term.args,
-                ) {
-                    return Ok(());
-                }
-            }
+        if let Some(projection_pred) = assumption.as_projection_clause()
+            && projection_pred.item_def_id() == goal.predicate.def_id()
+            && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                goal.predicate.alias.args,
+                projection_pred.skip_binder().projection_term.args,
+            )
+        {
+            Ok(())
+        } else {
+            Err(NoSolution)
         }
-
-        Err(NoSolution)
     }
 
     fn match_assumption(
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 8aaa8e9ca87..6c9fb63b579 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -127,33 +127,32 @@ where
         goal: Goal<I, Self>,
         assumption: I::Clause,
     ) -> Result<(), NoSolution> {
-        if let Some(trait_clause) = assumption.as_trait_clause() {
-            if trait_clause.polarity() != goal.predicate.polarity {
-                return Err(NoSolution);
-            }
-
-            if trait_clause.def_id() == goal.predicate.def_id() {
-                if DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
-                    goal.predicate.trait_ref.args,
-                    trait_clause.skip_binder().trait_ref.args,
-                ) {
-                    return Ok(());
-                }
-            }
-
+        fn trait_def_id_matches<I: Interner>(
+            cx: I,
+            clause_def_id: I::DefId,
+            goal_def_id: I::DefId,
+        ) -> bool {
+            clause_def_id == goal_def_id
             // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
-            // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
-            // are syntactic sugar for a lack of bounds so don't need this.
-            if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
-                && ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
-            {
-                let meta_sized_clause =
-                    trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
-                return Self::fast_reject_assumption(ecx, goal, meta_sized_clause);
-            }
+            // check for a `MetaSized` supertrait being matched against a `Sized` assumption.
+            //
+            // `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
+                || (cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
+                    && cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
         }
 
-        Err(NoSolution)
+        if let Some(trait_clause) = assumption.as_trait_clause()
+            && trait_clause.polarity() == goal.predicate.polarity
+            && trait_def_id_matches(ecx.cx(), trait_clause.def_id(), goal.predicate.def_id())
+            && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                goal.predicate.trait_ref.args,
+                trait_clause.skip_binder().trait_ref.args,
+            )
+        {
+            return Ok(());
+        } else {
+            Err(NoSolution)
+        }
     }
 
     fn match_assumption(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a51f4e3dc07..4b8762d0dd1 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1977,6 +1977,8 @@ symbols! {
         simd_fmin,
         simd_fsin,
         simd_fsqrt,
+        simd_funnel_shl,
+        simd_funnel_shr,
         simd_gather,
         simd_ge,
         simd_gt,
@@ -2004,6 +2006,7 @@ symbols! {
         simd_relaxed_fma,
         simd_rem,
         simd_round,
+        simd_round_ties_even,
         simd_saturating_add,
         simd_saturating_sub,
         simd_scatter,
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index 177bad96595..7ffcf7b5d96 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -320,10 +320,10 @@ pub fn supertrait_def_ids<I: Interner>(
         let trait_def_id = stack.pop()?;
 
         for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() {
-            if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
-                if set.insert(data.def_id()) {
-                    stack.push(data.def_id());
-                }
+            if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder()
+                && set.insert(data.def_id())
+            {
+                stack.push(data.def_id());
             }
         }
 
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index 2bc12d0a23b..8ba9e7105d6 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -117,12 +117,20 @@ impl<I: Interner> TypingMode<I> {
     }
 
     pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
-        TypingMode::Borrowck { defining_opaque_types: cx.opaque_types_defined_by(body_def_id) }
+        let defining_opaque_types = cx.opaque_types_defined_by(body_def_id);
+        if defining_opaque_types.is_empty() {
+            TypingMode::non_body_analysis()
+        } else {
+            TypingMode::Borrowck { defining_opaque_types }
+        }
     }
 
     pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
-        TypingMode::PostBorrowckAnalysis {
-            defined_opaque_types: cx.opaque_types_defined_by(body_def_id),
+        let defined_opaque_types = cx.opaque_types_defined_by(body_def_id);
+        if defined_opaque_types.is_empty() {
+            TypingMode::non_body_analysis()
+        } else {
+            TypingMode::PostBorrowckAnalysis { defined_opaque_types }
         }
     }
 }
diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs
index e42639c6807..79f6bc5dabb 100644
--- a/compiler/rustc_type_ir/src/relate/solver_relating.rs
+++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs
@@ -284,12 +284,12 @@ where
         }
 
         // If they have no bound vars, relate normally.
-        if let Some(a_inner) = a.no_bound_vars() {
-            if let Some(b_inner) = b.no_bound_vars() {
-                self.relate(a_inner, b_inner)?;
-                return Ok(a);
-            }
-        };
+        if let Some(a_inner) = a.no_bound_vars()
+            && let Some(b_inner) = b.no_bound_vars()
+        {
+            self.relate(a_inner, b_inner)?;
+            return Ok(a);
+        }
 
         match self.ambient_variance {
             // Checks whether `for<..> sub <: for<..> sup` holds.
diff --git a/compiler/rustc_type_ir/src/search_graph/global_cache.rs b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
index 1b99cc820f1..eb56c1af408 100644
--- a/compiler/rustc_type_ir/src/search_graph/global_cache.rs
+++ b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
@@ -80,31 +80,29 @@ impl<X: Cx> GlobalCache<X> {
         mut candidate_is_applicable: impl FnMut(&NestedGoals<X>) -> bool,
     ) -> Option<CacheData<'a, X>> {
         let entry = self.map.get(&input)?;
-        if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success {
-            if available_depth.cache_entry_is_applicable(required_depth)
-                && candidate_is_applicable(nested_goals)
-            {
-                return Some(CacheData {
-                    result: cx.get_tracked(&result),
-                    required_depth,
-                    encountered_overflow: false,
-                    nested_goals,
-                });
-            }
+        if let Some(Success { required_depth, ref nested_goals, ref result }) = entry.success
+            && available_depth.cache_entry_is_applicable(required_depth)
+            && candidate_is_applicable(nested_goals)
+        {
+            return Some(CacheData {
+                result: cx.get_tracked(&result),
+                required_depth,
+                encountered_overflow: false,
+                nested_goals,
+            });
         }
 
         let additional_depth = available_depth.0;
         if let Some(WithOverflow { nested_goals, result }) =
             entry.with_overflow.get(&additional_depth)
+            && candidate_is_applicable(nested_goals)
         {
-            if candidate_is_applicable(nested_goals) {
-                return Some(CacheData {
-                    result: cx.get_tracked(result),
-                    required_depth: additional_depth,
-                    encountered_overflow: true,
-                    nested_goals,
-                });
-            }
+            return Some(CacheData {
+                result: cx.get_tracked(result),
+                required_depth: additional_depth,
+                encountered_overflow: true,
+                nested_goals,
+            });
         }
 
         None
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 40efc263068..11533ab6aa4 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -126,6 +126,40 @@ pub unsafe fn simd_shl<T>(lhs: T, rhs: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn simd_shr<T>(lhs: T, rhs: T) -> T;
 
+/// Funnel Shifts vector left elementwise, with UB on overflow.
+///
+/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
+/// creating a vector of the same length, but with each element being twice as
+/// wide. Then shift this vector left elementwise by `shift`, shifting in zeros,
+/// and extract the most significant half of each of the elements. If `a` and `b`
+/// are the same, this is equivalent to an elementwise rotate left operation.
+///
+/// `T` must be a vector of integers.
+///
+/// # Safety
+///
+/// Each element of `shift` must be less than `<int>::BITS`.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_funnel_shl<T>(a: T, b: T, shift: T) -> T;
+
+/// Funnel Shifts vector right elementwise, with UB on overflow.
+///
+/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
+/// creating a vector of the same length, but with each element being twice as
+/// wide. Then shift this vector right elementwise by `shift`, shifting in zeros,
+/// and extract the least significant half of each of the elements. If `a` and `b`
+/// are the same, this is equivalent to an elementwise rotate right operation.
+///
+/// `T` must be a vector of integers.
+///
+/// # Safety
+///
+/// Each element of `shift` must be less than `<int>::BITS`.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_funnel_shr<T>(a: T, b: T, shift: T) -> T;
+
 /// "Ands" vectors elementwise.
 ///
 /// `T` must be a vector of integers.
@@ -678,6 +712,14 @@ pub unsafe fn simd_floor<T>(x: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn simd_round<T>(x: T) -> T;
 
+/// Rounds each element to the closest integer-valued float.
+/// Ties are resolved by rounding to the number with an even least significant digit
+///
+/// `T` must be a vector of floats.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_round_ties_even<T>(x: T) -> T;
+
 /// Returns the integer part of each element as an integer-valued float.
 /// In other words, non-integer values are truncated towards zero.
 ///
diff --git a/library/std/src/sys/fs/windows/remove_dir_all.rs b/library/std/src/sys/fs/windows/remove_dir_all.rs
index 06734f9e309..c8b1a076768 100644
--- a/library/std/src/sys/fs/windows/remove_dir_all.rs
+++ b/library/std/src/sys/fs/windows/remove_dir_all.rs
@@ -33,7 +33,7 @@ use core::sync::atomic::{Atomic, AtomicU32, Ordering};
 
 use super::{AsRawHandle, DirBuff, File, FromRawHandle};
 use crate::sys::c;
-use crate::sys::pal::api::WinError;
+use crate::sys::pal::api::{UnicodeStrRef, WinError, unicode_str};
 use crate::thread;
 
 // The maximum number of times to spin when waiting for deletes to complete.
@@ -74,7 +74,7 @@ unsafe fn nt_open_file(
 /// `options` will be OR'd with `FILE_OPEN_REPARSE_POINT`.
 fn open_link_no_reparse(
     parent: &File,
-    path: &[u16],
+    path: UnicodeStrRef<'_>,
     access: u32,
     options: u32,
 ) -> Result<Option<File>, WinError> {
@@ -90,9 +90,8 @@ fn open_link_no_reparse(
     static ATTRIBUTES: Atomic<u32> = AtomicU32::new(c::OBJ_DONT_REPARSE);
 
     let result = unsafe {
-        let mut path_str = c::UNICODE_STRING::from_ref(path);
         let mut object = c::OBJECT_ATTRIBUTES {
-            ObjectName: &mut path_str,
+            ObjectName: path.as_ptr(),
             RootDirectory: parent.as_raw_handle(),
             Attributes: ATTRIBUTES.load(Ordering::Relaxed),
             ..c::OBJECT_ATTRIBUTES::with_length()
@@ -129,7 +128,7 @@ fn open_link_no_reparse(
     }
 }
 
-fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
+fn open_dir(parent: &File, name: UnicodeStrRef<'_>) -> Result<Option<File>, WinError> {
     // Open the directory for synchronous directory listing.
     open_link_no_reparse(
         parent,
@@ -140,7 +139,7 @@ fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
     )
 }
 
-fn delete(parent: &File, name: &[u16]) -> Result<(), WinError> {
+fn delete(parent: &File, name: UnicodeStrRef<'_>) -> Result<(), WinError> {
     // Note that the `delete` function consumes the opened file to ensure it's
     // dropped immediately. See module comments for why this is important.
     match open_link_no_reparse(parent, name, c::DELETE, 0) {
@@ -179,8 +178,9 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
     'outer: while let Some(dir) = dirlist.pop() {
         let more_data = dir.fill_dir_buff(&mut buffer, restart)?;
         for (name, is_directory) in buffer.iter() {
+            let name = unicode_str!(&name);
             if is_directory {
-                let Some(subdir) = open_dir(&dir, &name)? else { continue };
+                let Some(subdir) = open_dir(&dir, name)? else { continue };
                 dirlist.push(dir);
                 dirlist.push(subdir);
                 continue 'outer;
@@ -188,7 +188,7 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
                 // Attempt to delete, retrying on sharing violation errors as these
                 // can often be very temporary. E.g. if something takes just a
                 // bit longer than expected to release a file handle.
-                retry(|| delete(&dir, &name), WinError::SHARING_VIOLATION)?;
+                retry(|| delete(&dir, name), WinError::SHARING_VIOLATION)?;
             }
         }
         if more_data {
@@ -197,7 +197,8 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
         } else {
             // Attempt to delete, retrying on not empty errors because we may
             // need to wait some time for files to be removed from the filesystem.
-            retry(|| delete(&dir, &[]), WinError::DIR_NOT_EMPTY)?;
+            let name = unicode_str!("");
+            retry(|| delete(&dir, name), WinError::DIR_NOT_EMPTY)?;
             restart = true;
         }
     }
diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs
index 773455c572f..25a6c2d7d8e 100644
--- a/library/std/src/sys/pal/windows/api.rs
+++ b/library/std/src/sys/pal/windows/api.rs
@@ -30,6 +30,7 @@
 //! should go in sys/pal/windows/mod.rs rather than here. See `IoResult` as an example.
 
 use core::ffi::c_void;
+use core::marker::PhantomData;
 
 use super::c;
 
@@ -291,3 +292,75 @@ impl WinError {
     pub const TIMEOUT: Self = Self::new(c::ERROR_TIMEOUT);
     // tidy-alphabetical-end
 }
+
+/// A wrapper around a UNICODE_STRING that is equivalent to `&[u16]`.
+///
+/// It is preferable to use the `unicode_str!` macro as that contains mitigations for  #143078.
+///
+/// If the MaximumLength field of the underlying UNICODE_STRING is greater than
+/// the Length field then you can test if the string is null terminated by inspecting
+/// the u16 directly after the string. You cannot otherwise depend on nul termination.
+#[derive(Copy, Clone)]
+pub struct UnicodeStrRef<'a> {
+    s: c::UNICODE_STRING,
+    lifetime: PhantomData<&'a [u16]>,
+}
+
+static EMPTY_STRING_NULL_TERMINATED: &[u16] = &[0];
+
+impl UnicodeStrRef<'_> {
+    const fn new(slice: &[u16], is_null_terminated: bool) -> Self {
+        let (len, max_len, ptr) = if slice.is_empty() {
+            (0, 2, EMPTY_STRING_NULL_TERMINATED.as_ptr().cast_mut())
+        } else {
+            let len = slice.len() - (is_null_terminated as usize);
+            (len * 2, size_of_val(slice), slice.as_ptr().cast_mut())
+        };
+        Self {
+            s: c::UNICODE_STRING { Length: len as _, MaximumLength: max_len as _, Buffer: ptr },
+            lifetime: PhantomData,
+        }
+    }
+
+    pub const fn from_slice_with_nul(slice: &[u16]) -> Self {
+        if !slice.is_empty() {
+            debug_assert!(slice[slice.len() - 1] == 0);
+        }
+        Self::new(slice, true)
+    }
+
+    pub const fn from_slice(slice: &[u16]) -> Self {
+        Self::new(slice, false)
+    }
+
+    /// Returns a pointer to the underlying UNICODE_STRING
+    pub const fn as_ptr(&self) -> *const c::UNICODE_STRING {
+        &self.s
+    }
+}
+
+/// Create a UnicodeStringRef from a literal str or a u16 array.
+///
+/// To mitigate #143078, when using a literal str the created UNICODE_STRING
+/// will be nul terminated. The MaximumLength field of the UNICODE_STRING will
+/// be set greater than the Length field to indicate that a nul may be present.
+///
+/// If using a u16 array, the array is used exactly as provided and you cannot
+/// count on the string being nul terminated.
+/// This should generally be used for strings that come from the OS.
+///
+/// **NOTE:** we lack a UNICODE_STRING builder type as we don't currently have
+/// a use for it. If needing to dynamically build a UNICODE_STRING, the builder
+/// should try to ensure there's a nul one past the end of the string.
+pub macro unicode_str {
+    ($str:literal) => {const {
+        crate::sys::pal::windows::api::UnicodeStrRef::from_slice_with_nul(
+            crate::sys::pal::windows::api::wide_str!($str),
+        )
+    }},
+    ($array:expr) => {
+        crate::sys::pal::windows::api::UnicodeStrRef::from_slice(
+            $array,
+        )
+    }
+}
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 53dec105d0c..eee169d410a 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -37,13 +37,6 @@ pub fn nt_success(status: NTSTATUS) -> bool {
     status >= 0
 }
 
-impl UNICODE_STRING {
-    pub fn from_ref(slice: &[u16]) -> Self {
-        let len = size_of_val(slice);
-        Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
-    }
-}
-
 impl OBJECT_ATTRIBUTES {
     pub fn with_length() -> Self {
         Self {
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs
index bc5d05c4505..b5ccf037a4f 100644
--- a/library/std/src/sys/pal/windows/pipe.rs
+++ b/library/std/src/sys/pal/windows/pipe.rs
@@ -1,9 +1,8 @@
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
 use crate::ops::Neg;
 use crate::os::windows::prelude::*;
-use crate::sys::api::utf16;
-use crate::sys::c;
 use crate::sys::handle::Handle;
+use crate::sys::{api, c};
 use crate::sys_common::{FromInner, IntoInner};
 use crate::{mem, ptr};
 
@@ -73,8 +72,8 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
         // Open a handle to the pipe filesystem (`\??\PIPE\`).
         // This will be used when creating a new annon pipe.
         let pipe_fs = {
-            let path = c::UNICODE_STRING::from_ref(utf16!(r"\??\PIPE\"));
-            object_attributes.ObjectName = &path;
+            let path = api::unicode_str!(r"\??\PIPE\");
+            object_attributes.ObjectName = path.as_ptr();
             let mut pipe_fs = ptr::null_mut();
             let status = c::NtOpenFile(
                 &mut pipe_fs,
@@ -93,8 +92,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
 
         // From now on we're using handles instead of paths to create and open pipes.
         // So set the `ObjectName` to a zero length string.
+        // As a (perhaps overzealous) mitigation for #143078, we use the null pointer
+        // for empty.Buffer instead of unicode_str!("").
+        // There's no difference to the OS itself but it's possible that third party
+        // DLLs which hook in to processes could be relying on the exact form of this string.
         let empty = c::UNICODE_STRING::default();
-        object_attributes.ObjectName = &empty;
+        object_attributes.ObjectName = &raw const empty;
 
         // Create our side of the pipe for async access.
         let ours = {
diff --git a/library/stdarch/crates/intrinsic-test/README.md b/library/stdarch/crates/intrinsic-test/README.md
index 260d59fca80..bea95f91e9e 100644
--- a/library/stdarch/crates/intrinsic-test/README.md
+++ b/library/stdarch/crates/intrinsic-test/README.md
@@ -7,7 +7,7 @@ USAGE:
     intrinsic-test [FLAGS] [OPTIONS] <INPUT>
 
 FLAGS:
-        --a32              Run tests for A32 instrinsics instead of A64
+        --a32              Run tests for A32 intrinsics instead of A64
         --generate-only    Regenerate test programs, but don't build or run them
     -h, --help             Prints help information
     -V, --version          Prints version information
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 09dc476d68e..f7e62e1eccf 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -499,7 +499,7 @@ This directive takes comma-separated issue numbers as arguments, or `"unknown"`:
 - `//@ known-bug: rust-lang/chalk#123456`
   (allows arbitrary text before the `#`, which is useful when the issue is on another repo)
 - `//@ known-bug: unknown`
-  (when there is no known issue yet; preferrably open one if it does not already exist)
+  (when there is no known issue yet; preferably open one if it does not already exist)
 
 Do not include [error annotations](#error-annotations) in a test with
 `known-bug`. The test should still include other normal directives and
diff --git a/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
index a6fb25a55be..10464e500ec 100644
--- a/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
+++ b/src/doc/unstable-book/src/language-features/type-alias-impl-trait.md
@@ -64,7 +64,7 @@ struct HaveAlias {
 
 In this example, the concrete type referred to by `Alias` is guaranteed to be the same wherever `Alias` occurs.
 
-> Orginally this feature included type aliases as an associated type of a trait. In [#110237] this was split off to [`impl_trait_in_assoc_type`].
+> Originally this feature included type aliases as an associated type of a trait. In [#110237] this was split off to [`impl_trait_in_assoc_type`].
 
 ### `type_alias_impl_trait` in argument position.
 
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 192d4f444c2..d3123caaa47 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -81,6 +81,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
 name = "bitflags"
 version = "2.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -113,6 +122,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "capstone"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "015ef5d5ca1743e3f94af9509ba6bd2886523cfee46e48d15c2ef5216fd4ac9a"
+dependencies = [
+ "capstone-sys",
+ "libc",
+]
+
+[[package]]
+name = "capstone-sys"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2267cb8d16a1e4197863ec4284ffd1aec26fe7e57c58af46b02590a0235809a0"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
 name = "cargo-platform"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -151,6 +180,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
 name = "chrono"
 version = "0.4.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -224,7 +259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
 dependencies = [
  "lazy_static",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -243,7 +278,7 @@ dependencies = [
  "libc",
  "once_cell",
  "unicode-width 0.2.0",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -298,7 +333,7 @@ dependencies = [
  "libc",
  "option-ext",
  "redox_users",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -314,7 +349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
 dependencies = [
  "libc",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -334,6 +369,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
 name = "generic-array"
 version = "0.14.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -401,6 +442,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "ipc-channel"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fb8251fb7bcd9ccd3725ed8deae9fe7db8e586495c9eb5b0c52e6233e5e75ea"
+dependencies = [
+ "bincode",
+ "crossbeam-channel",
+ "fnv",
+ "lazy_static",
+ "libc",
+ "mio",
+ "rand 0.8.5",
+ "serde",
+ "tempfile",
+ "uuid",
+ "windows",
+]
+
+[[package]]
 name = "itoa"
 version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -534,23 +594,39 @@ dependencies = [
 ]
 
 [[package]]
+name = "mio"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+dependencies = [
+ "libc",
+ "log",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
 name = "miri"
 version = "0.1.0"
 dependencies = [
  "aes",
  "bitflags",
+ "capstone",
  "chrono",
  "chrono-tz",
  "colored",
  "directories",
  "getrandom 0.3.2",
+ "ipc-channel",
  "libc",
  "libffi",
  "libloading",
  "measureme",
+ "nix",
  "rand 0.9.0",
  "regex",
  "rustc_version",
+ "serde",
  "smallvec",
  "tempfile",
  "tikv-jemalloc-sys",
@@ -558,6 +634,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "nix"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+]
+
+[[package]]
 name = "num-traits"
 version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -748,6 +836,8 @@ version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
  "rand_core 0.6.4",
 ]
 
@@ -757,13 +847,23 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
 dependencies = [
- "rand_chacha",
+ "rand_chacha 0.9.0",
  "rand_core 0.9.3",
  "zerocopy",
 ]
 
 [[package]]
 name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
@@ -777,6 +877,9 @@ name = "rand_core"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.15",
+]
 
 [[package]]
 name = "rand_core"
@@ -879,7 +982,7 @@ dependencies = [
  "errno",
  "libc",
  "linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -993,7 +1096,7 @@ dependencies = [
  "getrandom 0.3.2",
  "once_cell",
  "rustix",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -1148,6 +1251,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
 
 [[package]]
+name = "uuid"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
+dependencies = [
+ "getrandom 0.3.2",
+]
+
+[[package]]
 name = "valuable"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1242,6 +1354,79 @@ dependencies = [
 ]
 
 [[package]]
+name = "windows"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
+dependencies = [
+ "windows-core",
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-result",
+ "windows-strings",
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
+dependencies = [
+ "windows-result",
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index a314488bb25..0b4b8e26bb8 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -40,6 +40,12 @@ libc = "0.2"
 libffi = "4.0.0"
 libloading = "0.8"
 
+[target.'cfg(target_os = "linux")'.dependencies]
+nix = { version = "0.30.1", features = ["mman", "ptrace", "signal"] }
+ipc-channel = "0.19.0"
+serde = { version = "1.0.219", features = ["derive"] }
+capstone = "0.13"
+
 [dev-dependencies]
 ui_test = "0.29.1"
 colored = "2"
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 3031d2c744a..e609fb9b6f9 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -419,6 +419,9 @@ to Miri failing to detect cases of undefined behavior in a program.
   Finally, the flag is **unsound** in the sense that Miri stops tracking details such as
   initialization and provenance on memory shared with native code, so it is easily possible to write
   code that has UB which is missed by Miri.
+* `-Zmiri-native-lib-enable-tracing` enables the WIP detailed tracing mode for invoking native code.
+  Note that this flag is only meaningful on Linux systems; other Unixes (currently) do not support
+  tracing mode.
 * `-Zmiri-measureme=<name>` enables `measureme` profiling for the interpreted program.
    This can be used to find which parts of your program are executing slowly under Miri.
    The profile is written out to a file inside a directory called `<name>`, and can be processed
diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs
index 86362145d47..d18e9c7791f 100644
--- a/src/tools/miri/miri-script/src/commands.rs
+++ b/src/tools/miri/miri-script/src/commands.rs
@@ -32,6 +32,7 @@ impl MiriEnv {
         &mut self,
         quiet: bool,
         target: Option<impl AsRef<OsStr>>,
+        features: &[String],
     ) -> Result<PathBuf> {
         if let Some(miri_sysroot) = self.sh.var_os("MIRI_SYSROOT") {
             // Sysroot already set, use that.
@@ -39,8 +40,8 @@ impl MiriEnv {
         }
 
         // Make sure everything is built. Also Miri itself.
-        self.build(".", &[], quiet)?;
-        self.build("cargo-miri", &[], quiet)?;
+        self.build(".", features, &[], quiet)?;
+        self.build("cargo-miri", &[], &[], quiet)?;
 
         let target_flag = if let Some(target) = &target {
             vec![OsStr::new("--target"), target.as_ref()]
@@ -58,7 +59,7 @@ impl MiriEnv {
         }
 
         let mut cmd = self
-            .cargo_cmd("cargo-miri", "run")
+            .cargo_cmd("cargo-miri", "run", &[])
             .arg("--quiet")
             .arg("--")
             .args(&["miri", "setup", "--print-sysroot"])
@@ -90,7 +91,9 @@ impl Command {
             Self::fmt(vec![])?;
         }
         if auto_clippy {
-            Self::clippy(vec![])?;
+            // no features for auto actions, see
+            // https://github.com/rust-lang/miri/pull/4396#discussion_r2149654845
+            Self::clippy(vec![], vec![])?;
         }
 
         Ok(())
@@ -175,16 +178,16 @@ impl Command {
         }
         // Then run the actual command.
         match self {
-            Command::Install { flags } => Self::install(flags),
-            Command::Build { flags } => Self::build(flags),
-            Command::Check { flags } => Self::check(flags),
-            Command::Test { bless, flags, target, coverage } =>
-                Self::test(bless, flags, target, coverage),
-            Command::Run { dep, verbose, target, edition, flags } =>
-                Self::run(dep, verbose, target, edition, flags),
-            Command::Doc { flags } => Self::doc(flags),
+            Command::Install { features, flags } => Self::install(features, flags),
+            Command::Build { features, flags } => Self::build(features, flags),
+            Command::Check { features, flags } => Self::check(features, flags),
+            Command::Test { bless, target, coverage, features, flags } =>
+                Self::test(bless, target, coverage, features, flags),
+            Command::Run { dep, verbose, target, edition, features, flags } =>
+                Self::run(dep, verbose, target, edition, features, flags),
+            Command::Doc { features, flags } => Self::doc(features, flags),
             Command::Fmt { flags } => Self::fmt(flags),
-            Command::Clippy { flags } => Self::clippy(flags),
+            Command::Clippy { features, flags } => Self::clippy(features, flags),
             Command::Bench { target, no_install, save_baseline, load_baseline, benches } =>
                 Self::bench(target, no_install, save_baseline, load_baseline, benches),
             Command::Toolchain { flags } => Self::toolchain(flags),
@@ -494,7 +497,7 @@ impl Command {
 
         if !no_install {
             // Make sure we have an up-to-date Miri installed and selected the right toolchain.
-            Self::install(vec![])?;
+            Self::install(vec![], vec![])?;
         }
         let results_json_dir = if save_baseline.is_some() || load_baseline.is_some() {
             Some(TempDir::new()?)
@@ -601,47 +604,48 @@ impl Command {
         Ok(())
     }
 
-    fn install(flags: Vec<String>) -> Result<()> {
+    fn install(features: Vec<String>, flags: Vec<String>) -> Result<()> {
         let e = MiriEnv::new()?;
-        e.install_to_sysroot(e.miri_dir.clone(), &flags)?;
-        e.install_to_sysroot(path!(e.miri_dir / "cargo-miri"), &flags)?;
+        e.install_to_sysroot(".", &features, &flags)?;
+        e.install_to_sysroot("cargo-miri", &[], &flags)?;
         Ok(())
     }
 
-    fn build(flags: Vec<String>) -> Result<()> {
+    fn build(features: Vec<String>, flags: Vec<String>) -> Result<()> {
         let e = MiriEnv::new()?;
-        e.build(".", &flags, /* quiet */ false)?;
-        e.build("cargo-miri", &flags, /* quiet */ false)?;
+        e.build(".", &features, &flags, /* quiet */ false)?;
+        e.build("cargo-miri", &[], &flags, /* quiet */ false)?;
         Ok(())
     }
 
-    fn check(flags: Vec<String>) -> Result<()> {
+    fn check(features: Vec<String>, flags: Vec<String>) -> Result<()> {
         let e = MiriEnv::new()?;
-        e.check(".", &flags)?;
-        e.check("cargo-miri", &flags)?;
+        e.check(".", &features, &flags)?;
+        e.check("cargo-miri", &[], &flags)?;
         Ok(())
     }
 
-    fn doc(flags: Vec<String>) -> Result<()> {
+    fn doc(features: Vec<String>, flags: Vec<String>) -> Result<()> {
         let e = MiriEnv::new()?;
-        e.doc(".", &flags)?;
-        e.doc("cargo-miri", &flags)?;
+        e.doc(".", &features, &flags)?;
+        e.doc("cargo-miri", &[], &flags)?;
         Ok(())
     }
 
-    fn clippy(flags: Vec<String>) -> Result<()> {
+    fn clippy(features: Vec<String>, flags: Vec<String>) -> Result<()> {
         let e = MiriEnv::new()?;
-        e.clippy(".", &flags)?;
-        e.clippy("cargo-miri", &flags)?;
-        e.clippy("miri-script", &flags)?;
+        e.clippy(".", &features, &flags)?;
+        e.clippy("cargo-miri", &[], &flags)?;
+        e.clippy("miri-script", &[], &flags)?;
         Ok(())
     }
 
     fn test(
         bless: bool,
-        mut flags: Vec<String>,
         target: Option<String>,
         coverage: bool,
+        features: Vec<String>,
+        mut flags: Vec<String>,
     ) -> Result<()> {
         let mut e = MiriEnv::new()?;
 
@@ -652,7 +656,7 @@ impl Command {
         }
 
         // Prepare a sysroot. (Also builds cargo-miri, which we need.)
-        e.build_miri_sysroot(/* quiet */ false, target.as_deref())?;
+        e.build_miri_sysroot(/* quiet */ false, target.as_deref(), &features)?;
 
         // Forward information to test harness.
         if bless {
@@ -672,10 +676,10 @@ impl Command {
 
         // Then test, and let caller control flags.
         // Only in root project as `cargo-miri` has no tests.
-        e.test(".", &flags)?;
+        e.test(".", &features, &flags)?;
 
         if let Some(coverage) = &coverage {
-            coverage.show_coverage_report(&e)?;
+            coverage.show_coverage_report(&e, &features)?;
         }
 
         Ok(())
@@ -686,14 +690,17 @@ impl Command {
         verbose: bool,
         target: Option<String>,
         edition: Option<String>,
+        features: Vec<String>,
         flags: Vec<String>,
     ) -> Result<()> {
         let mut e = MiriEnv::new()?;
 
         // Preparation: get a sysroot, and get the miri binary.
-        let miri_sysroot = e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref())?;
-        let miri_bin =
-            e.build_get_binary(".").context("failed to get filename of miri executable")?;
+        let miri_sysroot =
+            e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref(), &features)?;
+        let miri_bin = e
+            .build_get_binary(".", &features)
+            .context("failed to get filename of miri executable")?;
 
         // More flags that we will pass before `flags`
         // (because `flags` may contain `--`).
@@ -718,7 +725,7 @@ impl Command {
         // The basic command that executes the Miri driver.
         let mut cmd = if dep {
             // We invoke the test suite as that has all the logic for running with dependencies.
-            e.cargo_cmd(".", "test")
+            e.cargo_cmd(".", "test", &features)
                 .args(&["--test", "ui"])
                 .args(quiet_flag)
                 .arg("--")
diff --git a/src/tools/miri/miri-script/src/coverage.rs b/src/tools/miri/miri-script/src/coverage.rs
index 8cafcea0d16..cdf2bbb9330 100644
--- a/src/tools/miri/miri-script/src/coverage.rs
+++ b/src/tools/miri/miri-script/src/coverage.rs
@@ -49,7 +49,7 @@ impl CoverageReport {
 
     /// show_coverage_report will print coverage information using the artifact
     /// files in `self.path`.
-    pub fn show_coverage_report(&self, e: &MiriEnv) -> Result<()> {
+    pub fn show_coverage_report(&self, e: &MiriEnv, features: &[String]) -> Result<()> {
         let profraw_files = self.profraw_files()?;
 
         let profdata_bin = path!(e.libdir / ".." / "bin" / "llvm-profdata");
@@ -63,8 +63,9 @@ impl CoverageReport {
 
         // Create the coverage report.
         let cov_bin = path!(e.libdir / ".." / "bin" / "llvm-cov");
-        let miri_bin =
-            e.build_get_binary(".").context("failed to get filename of miri executable")?;
+        let miri_bin = e
+            .build_get_binary(".", features)
+            .context("failed to get filename of miri executable")?;
         cmd!(
             e.sh,
             "{cov_bin} report --instr-profile={merged_file} --object {miri_bin} --sources src/"
diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs
index 6aab2f79bd7..673d658cf1d 100644
--- a/src/tools/miri/miri-script/src/main.rs
+++ b/src/tools/miri/miri-script/src/main.rs
@@ -14,24 +14,40 @@ pub enum Command {
     /// Sets up the rpath such that the installed binary should work in any
     /// working directory.
     Install {
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `cargo install`.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
     },
     /// Build Miri.
     Build {
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `cargo build`.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
     },
     /// Check Miri.
     Check {
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `cargo check`.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
     },
     /// Check Miri with Clippy.
     Clippy {
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `cargo clippy`.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
@@ -47,6 +63,10 @@ pub enum Command {
         /// Produce coverage report.
         #[arg(long)]
         coverage: bool,
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to the test harness.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
@@ -67,6 +87,10 @@ pub enum Command {
         /// The Rust edition.
         #[arg(long)]
         edition: Option<String>,
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `miri`.
         ///
         /// The flags set in `MIRIFLAGS` are added in front of these flags.
@@ -75,6 +99,10 @@ pub enum Command {
     },
     /// Build documentation.
     Doc {
+        /// Pass features to cargo invocations on the "miri" crate in the root. This option does
+        /// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
+        #[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
+        features: Vec<String>,
         /// Flags that are passed through to `cargo doc`.
         #[arg(trailing_var_arg = true, allow_hyphen_values = true)]
         flags: Vec<String>,
@@ -144,13 +172,13 @@ impl Command {
         }
 
         match self {
-            Self::Install { flags }
-            | Self::Build { flags }
-            | Self::Check { flags }
-            | Self::Doc { flags }
+            Self::Install { flags, .. }
+            | Self::Build { flags, .. }
+            | Self::Check { flags, .. }
+            | Self::Doc { flags, .. }
             | Self::Fmt { flags }
             | Self::Toolchain { flags }
-            | Self::Clippy { flags }
+            | Self::Clippy { flags, .. }
             | Self::Run { flags, .. }
             | Self::Test { flags, .. } => {
                 flags.extend(remainder);
diff --git a/src/tools/miri/miri-script/src/util.rs b/src/tools/miri/miri-script/src/util.rs
index 5c2a055990f..c100cf195ba 100644
--- a/src/tools/miri/miri-script/src/util.rs
+++ b/src/tools/miri/miri-script/src/util.rs
@@ -26,6 +26,12 @@ pub fn flagsplit(flags: &str) -> Vec<String> {
     flags.split(' ').map(str::trim).filter(|s| !s.is_empty()).map(str::to_string).collect()
 }
 
+/// Turns a list of features into a list of arguments to pass to cargo invocations.
+/// Each feature will go in its own argument, e.g. "--features feat1 --features feat2".
+fn features_to_args(features: &[String]) -> impl IntoIterator<Item = &str> {
+    features.iter().flat_map(|feat| ["--features", feat])
+}
+
 /// Some extra state we track for building Miri, such as the right RUSTFLAGS.
 pub struct MiriEnv {
     /// miri_dir is the root of the miri repository checkout we are working in.
@@ -116,44 +122,70 @@ impl MiriEnv {
         Ok(MiriEnv { miri_dir, toolchain, sh, sysroot, cargo_extra_flags, libdir })
     }
 
-    pub fn cargo_cmd(&self, crate_dir: impl AsRef<OsStr>, cmd: &str) -> Cmd<'_> {
+    /// Make sure the `features` you pass here exist for the specified `crate_dir`. For example, the
+    /// "--features" parameter of [crate::Command]s is intended only for the "miri" root crate.
+    pub fn cargo_cmd(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        cmd: &str,
+        features: &[String],
+    ) -> Cmd<'_> {
         let MiriEnv { toolchain, cargo_extra_flags, .. } = self;
         let manifest_path = path!(self.miri_dir / crate_dir.as_ref() / "Cargo.toml");
+        let features = features_to_args(features);
         cmd!(
             self.sh,
-            "cargo +{toolchain} {cmd} {cargo_extra_flags...} --manifest-path {manifest_path}"
+            "cargo +{toolchain} {cmd} {cargo_extra_flags...} --manifest-path {manifest_path} {features...}"
         )
     }
 
+    /// Make sure the `features` you pass here exist for the specified `crate_dir`. For example, the
+    /// "--features" parameter of [crate::Command]s is intended only for the "miri" root crate.
     pub fn install_to_sysroot(
         &self,
-        path: impl AsRef<OsStr>,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
         args: impl IntoIterator<Item = impl AsRef<OsStr>>,
     ) -> Result<()> {
         let MiriEnv { sysroot, toolchain, cargo_extra_flags, .. } = self;
-        let path = path!(self.miri_dir / path.as_ref());
+        let path = path!(self.miri_dir / crate_dir.as_ref());
+        let features = features_to_args(features);
         // Install binaries to the miri toolchain's `sysroot` so they do not interact with other toolchains.
         // (Not using `cargo_cmd` as `install` is special and doesn't use `--manifest-path`.)
-        cmd!(self.sh, "cargo +{toolchain} install {cargo_extra_flags...} --path {path} --force --root {sysroot} {args...}").run()?;
+        cmd!(self.sh, "cargo +{toolchain} install {cargo_extra_flags...} --path {path} --force --root {sysroot} {features...} {args...}").run()?;
         Ok(())
     }
 
-    pub fn build(&self, crate_dir: impl AsRef<OsStr>, args: &[String], quiet: bool) -> Result<()> {
+    pub fn build(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+        args: &[String],
+        quiet: bool,
+    ) -> Result<()> {
         let quiet_flag = if quiet { Some("--quiet") } else { None };
         // We build all targets, since building *just* the bin target doesnot include
         // `dev-dependencies` and that changes feature resolution. This also gets us more
         // parallelism in `./miri test` as we build Miri and its tests together.
-        let mut cmd =
-            self.cargo_cmd(crate_dir, "build").args(&["--all-targets"]).args(quiet_flag).args(args);
+        let mut cmd = self
+            .cargo_cmd(crate_dir, "build", features)
+            .args(&["--all-targets"])
+            .args(quiet_flag)
+            .args(args);
         cmd.set_quiet(quiet);
         cmd.run()?;
         Ok(())
     }
 
     /// Returns the path to the main crate binary. Assumes that `build` has been called before.
-    pub fn build_get_binary(&self, crate_dir: impl AsRef<OsStr>) -> Result<PathBuf> {
-        let cmd =
-            self.cargo_cmd(crate_dir, "build").args(&["--all-targets", "--message-format=json"]);
+    pub fn build_get_binary(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+    ) -> Result<PathBuf> {
+        let cmd = self
+            .cargo_cmd(crate_dir, "build", features)
+            .args(&["--all-targets", "--message-format=json"]);
         let output = cmd.output()?;
         let mut bin = None;
         for line in output.stdout.lines() {
@@ -174,23 +206,43 @@ impl MiriEnv {
         bin.ok_or_else(|| anyhow!("found no binary in cargo output"))
     }
 
-    pub fn check(&self, crate_dir: impl AsRef<OsStr>, args: &[String]) -> Result<()> {
-        self.cargo_cmd(crate_dir, "check").arg("--all-targets").args(args).run()?;
+    pub fn check(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+        args: &[String],
+    ) -> Result<()> {
+        self.cargo_cmd(crate_dir, "check", features).arg("--all-targets").args(args).run()?;
         Ok(())
     }
 
-    pub fn doc(&self, crate_dir: impl AsRef<OsStr>, args: &[String]) -> Result<()> {
-        self.cargo_cmd(crate_dir, "doc").args(args).run()?;
+    pub fn doc(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+        args: &[String],
+    ) -> Result<()> {
+        self.cargo_cmd(crate_dir, "doc", features).args(args).run()?;
         Ok(())
     }
 
-    pub fn clippy(&self, crate_dir: impl AsRef<OsStr>, args: &[String]) -> Result<()> {
-        self.cargo_cmd(crate_dir, "clippy").arg("--all-targets").args(args).run()?;
+    pub fn clippy(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+        args: &[String],
+    ) -> Result<()> {
+        self.cargo_cmd(crate_dir, "clippy", features).arg("--all-targets").args(args).run()?;
         Ok(())
     }
 
-    pub fn test(&self, crate_dir: impl AsRef<OsStr>, args: &[String]) -> Result<()> {
-        self.cargo_cmd(crate_dir, "test").args(args).run()?;
+    pub fn test(
+        &self,
+        crate_dir: impl AsRef<OsStr>,
+        features: &[String],
+        args: &[String],
+    ) -> Result<()> {
+        self.cargo_cmd(crate_dir, "test", features).args(args).run()?;
         Ok(())
     }
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 90c6e31e9d1..b2ab17fd76a 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-0cbc0764380630780a275c437260e4d4d5f28c92
+d41e12f1f4e4884c356f319b881921aa37040de5
diff --git a/src/tools/miri/src/alloc/isolated_alloc.rs b/src/tools/miri/src/alloc/isolated_alloc.rs
index 3a7879f372a..a7bb9b4da75 100644
--- a/src/tools/miri/src/alloc/isolated_alloc.rs
+++ b/src/tools/miri/src/alloc/isolated_alloc.rs
@@ -1,5 +1,7 @@
-use std::alloc::{self, Layout};
+use std::alloc::Layout;
+use std::ptr::NonNull;
 
+use nix::sys::mman;
 use rustc_index::bit_set::DenseBitSet;
 
 /// How many bytes of memory each bit in the bitset represents.
@@ -11,8 +13,8 @@ const COMPRESSION_FACTOR: usize = 4;
 pub struct IsolatedAlloc {
     /// Pointers to page-aligned memory that has been claimed by the allocator.
     /// Every pointer here must point to a page-sized allocation claimed via
-    /// the global allocator. These pointers are used for "small" allocations.
-    page_ptrs: Vec<*mut u8>,
+    /// mmap. These pointers are used for "small" allocations.
+    page_ptrs: Vec<NonNull<u8>>,
     /// Metadata about which bytes have been allocated on each page. The length
     /// of this vector must be the same as that of `page_ptrs`, and the domain
     /// size of the bitset must be exactly `page_size / COMPRESSION_FACTOR`.
@@ -24,7 +26,7 @@ pub struct IsolatedAlloc {
     page_infos: Vec<DenseBitSet<usize>>,
     /// Pointers to multiple-page-sized allocations. These must also be page-aligned,
     /// with their size stored as the second element of the vector.
-    huge_ptrs: Vec<(*mut u8, usize)>,
+    huge_ptrs: Vec<(NonNull<u8>, usize)>,
     /// The host (not emulated) page size.
     page_size: usize,
 }
@@ -52,20 +54,26 @@ impl IsolatedAlloc {
         Layout::from_size_align(size, align).unwrap()
     }
 
-    /// Returns the layout used to allocate the pages that hold small allocations.
+    /// For greater-than-page-sized allocations, returns the allocation size we need to request
+    /// including the slack we need to satisfy the alignment request.
     #[inline]
-    fn page_layout(&self) -> Layout {
-        Layout::from_size_align(self.page_size, self.page_size).unwrap()
-    }
-
-    /// If the allocation is greater than a page, then round to the nearest page #.
-    #[inline]
-    fn huge_normalized_layout(layout: Layout, page_size: usize) -> Layout {
+    fn huge_normalized_layout(&self, layout: Layout) -> usize {
         // Allocate in page-sized chunks
-        let size = layout.size().next_multiple_of(page_size);
+        let size = layout.size().next_multiple_of(self.page_size);
         // And make sure the align is at least one page
-        let align = std::cmp::max(layout.align(), page_size);
-        Layout::from_size_align(size, align).unwrap()
+        let align = std::cmp::max(layout.align(), self.page_size);
+        // pg_count gives us the # of pages needed to satisfy the size. For
+        // align > page_size where align = n * page_size, a sufficently-aligned
+        // address must exist somewhere in the range of
+        // some_page_aligned_address..some_page_aligned_address + (n-1) * page_size
+        // (since if some_page_aligned_address + n * page_size is sufficently aligned,
+        // then so is some_page_aligned_address itself per the definition of n, so we
+        // can avoid using that 1 extra page).
+        // Thus we allocate n-1 extra pages
+        let pg_count = size.div_ceil(self.page_size);
+        let extra_pages = align.strict_div(self.page_size).saturating_sub(1);
+
+        pg_count.strict_add(extra_pages).strict_mul(self.page_size)
     }
 
     /// Determined whether a given normalized (size, align) should be sent to
@@ -78,7 +86,7 @@ impl IsolatedAlloc {
     /// Allocates memory as described in `Layout`. This memory should be deallocated
     /// by calling `dealloc` on this same allocator.
     ///
-    /// SAFETY: See `alloc::alloc()`
+    /// SAFETY: See `alloc::alloc()`.
     pub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8 {
         // SAFETY: Upheld by caller
         unsafe { self.allocate(layout, false) }
@@ -86,7 +94,7 @@ impl IsolatedAlloc {
 
     /// Same as `alloc`, but zeroes out the memory.
     ///
-    /// SAFETY: See `alloc::alloc_zeroed()`
+    /// SAFETY: See `alloc::alloc_zeroed()`.
     pub unsafe fn alloc_zeroed(&mut self, layout: Layout) -> *mut u8 {
         // SAFETY: Upheld by caller
         unsafe { self.allocate(layout, true) }
@@ -95,14 +103,13 @@ impl IsolatedAlloc {
     /// Abstracts over the logic of `alloc_zeroed` vs `alloc`, as determined by
     /// the `zeroed` argument.
     ///
-    /// SAFETY: See `alloc::alloc()`, with the added restriction that `page_size`
-    /// corresponds to the host pagesize.
+    /// SAFETY: See `alloc::alloc()`.
     unsafe fn allocate(&mut self, layout: Layout, zeroed: bool) -> *mut u8 {
         let layout = IsolatedAlloc::normalized_layout(layout);
         if self.is_huge_alloc(&layout) {
             // SAFETY: Validity of `layout` upheld by caller; we checked that
             // the size and alignment are appropriate for being a huge alloc
-            unsafe { self.alloc_huge(layout, zeroed) }
+            unsafe { self.alloc_huge(layout) }
         } else {
             for (&mut page, pinfo) in std::iter::zip(&mut self.page_ptrs, &mut self.page_infos) {
                 // SAFETY: The value in `self.page_size` is used to allocate
@@ -132,7 +139,7 @@ impl IsolatedAlloc {
     unsafe fn alloc_small(
         page_size: usize,
         layout: Layout,
-        page: *mut u8,
+        page: NonNull<u8>,
         pinfo: &mut DenseBitSet<usize>,
         zeroed: bool,
     ) -> Option<*mut u8> {
@@ -159,7 +166,7 @@ impl IsolatedAlloc {
                         // zero out, even if we allocated more
                         ptr.write_bytes(0, layout.size());
                     }
-                    return Some(ptr);
+                    return Some(ptr.as_ptr());
                 }
             }
         }
@@ -167,26 +174,50 @@ impl IsolatedAlloc {
     }
 
     /// Expands the available memory pool by adding one page.
-    fn add_page(&mut self) -> (*mut u8, &mut DenseBitSet<usize>) {
-        // SAFETY: The system page size, which is the layout size, cannot be 0
-        let page_ptr = unsafe { alloc::alloc(self.page_layout()) };
+    fn add_page(&mut self) -> (NonNull<u8>, &mut DenseBitSet<usize>) {
+        // SAFETY: mmap is always safe to call when requesting anonymous memory
+        let page_ptr = unsafe {
+            libc::mmap(
+                std::ptr::null_mut(),
+                self.page_size,
+                libc::PROT_READ | libc::PROT_WRITE,
+                libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+                -1,
+                0,
+            )
+            .cast::<u8>()
+        };
+        assert_ne!(page_ptr.addr(), usize::MAX, "mmap failed");
         // `page_infos` has to have one bit for each `COMPRESSION_FACTOR`-sized chunk of bytes in the page.
-        assert!(self.page_size % COMPRESSION_FACTOR == 0);
+        assert!(self.page_size.is_multiple_of(COMPRESSION_FACTOR));
         self.page_infos.push(DenseBitSet::new_empty(self.page_size / COMPRESSION_FACTOR));
-        self.page_ptrs.push(page_ptr);
-        (page_ptr, self.page_infos.last_mut().unwrap())
+        self.page_ptrs.push(NonNull::new(page_ptr).unwrap());
+        (NonNull::new(page_ptr).unwrap(), self.page_infos.last_mut().unwrap())
     }
 
     /// Allocates in multiples of one page on the host system.
+    /// Will always be zeroed.
     ///
     /// SAFETY: Same as `alloc()`.
-    unsafe fn alloc_huge(&mut self, layout: Layout, zeroed: bool) -> *mut u8 {
-        let layout = IsolatedAlloc::huge_normalized_layout(layout, self.page_size);
-        // SAFETY: Upheld by caller
-        let ret =
-            unsafe { if zeroed { alloc::alloc_zeroed(layout) } else { alloc::alloc(layout) } };
-        self.huge_ptrs.push((ret, layout.size()));
-        ret
+    unsafe fn alloc_huge(&mut self, layout: Layout) -> *mut u8 {
+        let size = self.huge_normalized_layout(layout);
+        // SAFETY: mmap is always safe to call when requesting anonymous memory
+        let ret = unsafe {
+            libc::mmap(
+                std::ptr::null_mut(),
+                size,
+                libc::PROT_READ | libc::PROT_WRITE,
+                libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
+                -1,
+                0,
+            )
+            .cast::<u8>()
+        };
+        assert_ne!(ret.addr(), usize::MAX, "mmap failed");
+        self.huge_ptrs.push((NonNull::new(ret).unwrap(), size));
+        // huge_normalized_layout ensures that we've overallocated enough space
+        // for this to be valid.
+        ret.map_addr(|a| a.next_multiple_of(layout.align()))
     }
 
     /// Deallocates a pointer from this allocator.
@@ -215,15 +246,15 @@ impl IsolatedAlloc {
                 let page_ptr = self.page_ptrs.remove(idx);
                 // SAFETY: We checked that there are no outstanding allocations
                 // from us pointing to this page, and we know it was allocated
-                // with this layout
+                // in add_page as exactly a single page.
                 unsafe {
-                    alloc::dealloc(page_ptr, self.page_layout());
+                    assert_eq!(libc::munmap(page_ptr.as_ptr().cast(), self.page_size), 0);
                 }
             }
         }
     }
 
-    /// Returns the index of the page that this was deallocated from
+    /// Returns the index of the page that this was deallocated from.
     ///
     /// SAFETY: the pointer must have been allocated with `alloc_small`.
     unsafe fn dealloc_small(&mut self, ptr: *mut u8, layout: Layout) -> usize {
@@ -236,7 +267,7 @@ impl IsolatedAlloc {
         // This could be made faster if the list was sorted -- the allocator isn't fully optimized at the moment.
         let pinfo = std::iter::zip(&mut self.page_ptrs, &mut self.page_infos)
             .enumerate()
-            .find(|(_, (page, _))| page.addr() == page_addr);
+            .find(|(_, (page, _))| page.addr().get() == page_addr);
         let Some((idx_of_pinfo, (_, pinfo))) = pinfo else {
             panic!("Freeing in an unallocated page: {ptr:?}\nHolding pages {:?}", self.page_ptrs)
         };
@@ -252,19 +283,72 @@ impl IsolatedAlloc {
     /// SAFETY: Same as `dealloc()` with the added requirement that `layout`
     /// must ask for a size larger than the host pagesize.
     unsafe fn dealloc_huge(&mut self, ptr: *mut u8, layout: Layout) {
-        let layout = IsolatedAlloc::huge_normalized_layout(layout, self.page_size);
-        // Find the pointer matching in address with the one we got
+        let size = self.huge_normalized_layout(layout);
+        // Find the huge allocation containing `ptr`.
         let idx = self
             .huge_ptrs
             .iter()
-            .position(|pg| ptr.addr() == pg.0.addr())
+            .position(|&(pg, size)| {
+                pg.addr().get() <= ptr.addr() && ptr.addr() < pg.addr().get().strict_add(size)
+            })
             .expect("Freeing unallocated pages");
         // And kick it from the list
-        self.huge_ptrs.remove(idx);
-        // SAFETY: Caller ensures validity of the layout
+        let (un_offset_ptr, size2) = self.huge_ptrs.remove(idx);
+        assert_eq!(size, size2, "got wrong layout in dealloc");
+        // SAFETY: huge_ptrs contains allocations made with mmap with the size recorded there.
         unsafe {
-            alloc::dealloc(ptr, layout);
+            let ret = libc::munmap(un_offset_ptr.as_ptr().cast(), size);
+            assert_eq!(ret, 0);
+        }
+    }
+
+    /// Returns a vector of page addresses managed by the allocator.
+    pub fn pages(&self) -> Vec<usize> {
+        let mut pages: Vec<usize> =
+            self.page_ptrs.iter().map(|p| p.expose_provenance().get()).collect();
+        for (ptr, size) in self.huge_ptrs.iter() {
+            for i in 0..size / self.page_size {
+                pages.push(ptr.expose_provenance().get().strict_add(i * self.page_size));
+            }
+        }
+        pages
+    }
+
+    /// Protects all owned memory as `PROT_NONE`, preventing accesses.
+    ///
+    /// SAFETY: Accessing memory after this point will result in a segfault
+    /// unless it is first unprotected.
+    pub unsafe fn prepare_ffi(&mut self) -> Result<(), nix::errno::Errno> {
+        let prot = mman::ProtFlags::PROT_NONE;
+        unsafe { self.mprotect(prot) }
+    }
+
+    /// Deprotects all owned memory by setting it to RW. Erroring here is very
+    /// likely unrecoverable, so it may panic if applying those permissions
+    /// fails.
+    pub fn unprep_ffi(&mut self) {
+        let prot = mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE;
+        unsafe {
+            self.mprotect(prot).unwrap();
+        }
+    }
+
+    /// Applies `prot` to every page managed by the allocator.
+    ///
+    /// SAFETY: Accessing memory in violation of the protection flags will
+    /// trigger a segfault.
+    unsafe fn mprotect(&mut self, prot: mman::ProtFlags) -> Result<(), nix::errno::Errno> {
+        for &pg in &self.page_ptrs {
+            unsafe {
+                mman::mprotect(pg.cast(), self.page_size, prot)?;
+            }
+        }
+        for &(hpg, size) in &self.huge_ptrs {
+            unsafe {
+                mman::mprotect(hpg.cast(), size.next_multiple_of(self.page_size), prot)?;
+            }
         }
+        Ok(())
     }
 }
 
@@ -347,12 +431,15 @@ mod tests {
         sizes.append(&mut vec![256; 12]);
         // Give it some multi-page ones too
         sizes.append(&mut vec![32 * 1024; 4]);
+        sizes.push(4 * 1024);
 
         // Matching aligns for the sizes
         let mut aligns = vec![16; 12];
         aligns.append(&mut vec![256; 2]);
         aligns.append(&mut vec![64; 12]);
         aligns.append(&mut vec![4096; 4]);
+        // And one that requests align > page_size
+        aligns.push(64 * 1024);
 
         // Make sure we didn't mess up in the test itself!
         assert_eq!(sizes.len(), aligns.len());
diff --git a/src/tools/miri/src/alloc_addresses/reuse_pool.rs b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
index ab6aaed5e3e..b6cc017f772 100644
--- a/src/tools/miri/src/alloc_addresses/reuse_pool.rs
+++ b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
@@ -129,7 +129,7 @@ impl ReusePool {
         let idx = rng.random_range(begin..end);
         // Remove it from the pool and return.
         let (chosen_addr, chosen_size, chosen_thread, clock) = subpool.remove(idx);
-        debug_assert!(chosen_size >= size && chosen_addr % align.bytes() == 0);
+        debug_assert!(chosen_size >= size && chosen_addr.is_multiple_of(align.bytes()));
         debug_assert!(cross_thread_reuse || chosen_thread == thread);
         // No synchronization needed if we reused from the current thread.
         Some((chosen_addr, if chosen_thread == thread { None } else { Some(clock) }))
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 72057f812f9..92d21737ec6 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -227,10 +227,11 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
         } else {
             let return_code = miri::eval_entry(tcx, entry_def_id, entry_type, &config, None)
                 .unwrap_or_else(|| {
+                    //#[cfg(target_os = "linux")]
+                    //miri::native_lib::register_retcode_sv(rustc_driver::EXIT_FAILURE);
                     tcx.dcx().abort_if_errors();
                     rustc_driver::EXIT_FAILURE
                 });
-
             std::process::exit(return_code);
         }
 
@@ -723,6 +724,8 @@ fn main() {
             } else {
                 show_error!("-Zmiri-native-lib `{}` does not exist", filename);
             }
+        } else if arg == "-Zmiri-native-lib-enable-tracing" {
+            miri_config.native_lib_enable_tracing = true;
         } else if let Some(param) = arg.strip_prefix("-Zmiri-num-cpus=") {
             let num_cpus = param
                 .parse::<u32>()
@@ -793,6 +796,16 @@ fn main() {
 
     debug!("rustc arguments: {:?}", rustc_args);
     debug!("crate arguments: {:?}", miri_config.args);
+    #[cfg(target_os = "linux")]
+    if !miri_config.native_lib.is_empty() && miri_config.native_lib_enable_tracing {
+        // FIXME: This should display a diagnostic / warning on error
+        // SAFETY: If any other threads exist at this point (namely for the ctrlc
+        // handler), they will not interact with anything on the main rustc/Miri
+        // thread in an async-signal-unsafe way such as by accessing shared
+        // semaphores, etc.; the handler only calls `sleep()` and `exit()`, which
+        // are async-signal-safe, as is accessing atomics
+        //let _ = unsafe { miri::native_lib::init_sv() };
+    }
     run_compiler_and_exit(
         &rustc_args,
         &mut MiriCompilerCalls::new(miri_config, many_seeds, genmc_config),
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 99171b0349e..a0761cb07a1 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -468,10 +468,8 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // - when `extern type` is involved we use the size of the known prefix,
         // - if the pointer is not reborrowed (raw pointer) then we override the size
         //   to do a zero-length reborrow.
-        let reborrow_size = this
-            .size_and_align_of_val(place)?
-            .map(|(size, _)| size)
-            .unwrap_or(place.layout.size);
+        let reborrow_size =
+            this.size_and_align_of_val(place)?.map(|(size, _)| size).unwrap_or(place.layout.size);
         trace!("Creating new permission: {:?} with size {:?}", new_perm, reborrow_size);
 
         // This new tag is not guaranteed to actually be used.
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
index dcd5a6cb023..ad0a565dfd8 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs
@@ -327,7 +327,7 @@ mod tests {
         for i in 0..1000 {
             i.hash(&mut hasher);
             let rng = hasher.finish();
-            let op = rng % 3 == 0;
+            let op = rng.is_multiple_of(3);
             let key = (rng / 2) % 50;
             let val = (rng / 100) % 1000;
             if op {
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 38b5d4c0f06..c8a408fd8ac 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -582,88 +582,6 @@ impl<'tcx> ThreadManager<'tcx> {
         interp_ok(())
     }
 
-    /// Mark that the active thread tries to join the thread with `joined_thread_id`.
-    fn join_thread(
-        &mut self,
-        joined_thread_id: ThreadId,
-        data_race_handler: &mut GlobalDataRaceHandler,
-    ) -> InterpResult<'tcx> {
-        if self.threads[joined_thread_id].join_status == ThreadJoinStatus::Detached {
-            // On Windows this corresponds to joining on a closed handle.
-            throw_ub_format!("trying to join a detached thread");
-        }
-
-        fn after_join<'tcx>(
-            threads: &mut ThreadManager<'_>,
-            joined_thread_id: ThreadId,
-            data_race_handler: &mut GlobalDataRaceHandler,
-        ) -> InterpResult<'tcx> {
-            match data_race_handler {
-                GlobalDataRaceHandler::None => {}
-                GlobalDataRaceHandler::Vclocks(data_race) =>
-                    data_race.thread_joined(threads, joined_thread_id),
-                GlobalDataRaceHandler::Genmc(genmc_ctx) =>
-                    genmc_ctx.handle_thread_join(threads.active_thread, joined_thread_id)?,
-            }
-            interp_ok(())
-        }
-
-        // Mark the joined thread as being joined so that we detect if other
-        // threads try to join it.
-        self.threads[joined_thread_id].join_status = ThreadJoinStatus::Joined;
-        if !self.threads[joined_thread_id].state.is_terminated() {
-            trace!(
-                "{:?} blocked on {:?} when trying to join",
-                self.active_thread, joined_thread_id
-            );
-            // The joined thread is still running, we need to wait for it.
-            // Unce we get unblocked, perform the appropriate synchronization.
-            self.block_thread(
-                BlockReason::Join(joined_thread_id),
-                None,
-                callback!(
-                    @capture<'tcx> {
-                        joined_thread_id: ThreadId,
-                    }
-                    |this, unblock: UnblockKind| {
-                        assert_eq!(unblock, UnblockKind::Ready);
-                        after_join(&mut this.machine.threads, joined_thread_id, &mut this.machine.data_race)
-                    }
-                ),
-            );
-        } else {
-            // The thread has already terminated - establish happens-before
-            after_join(self, joined_thread_id, data_race_handler)?;
-        }
-        interp_ok(())
-    }
-
-    /// Mark that the active thread tries to exclusively join the thread with `joined_thread_id`.
-    /// If the thread is already joined by another thread, it will throw UB
-    fn join_thread_exclusive(
-        &mut self,
-        joined_thread_id: ThreadId,
-        data_race_handler: &mut GlobalDataRaceHandler,
-    ) -> InterpResult<'tcx> {
-        if self.threads[joined_thread_id].join_status == ThreadJoinStatus::Joined {
-            throw_ub_format!("trying to join an already joined thread");
-        }
-
-        if joined_thread_id == self.active_thread {
-            throw_ub_format!("trying to join itself");
-        }
-
-        // Sanity check `join_status`.
-        assert!(
-            self.threads
-                .iter()
-                .all(|thread| { !thread.state.is_blocked_on(BlockReason::Join(joined_thread_id)) }),
-            "this thread already has threads waiting for its termination"
-        );
-
-        self.join_thread(joined_thread_id, data_race_handler)
-    }
-
     /// Set the name of the given thread.
     pub fn set_thread_name(&mut self, thread: ThreadId, new_thread_name: Vec<u8>) {
         self.threads[thread].thread_name = Some(new_thread_name);
@@ -1114,20 +1032,102 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         this.machine.threads.detach_thread(thread_id, allow_terminated_joined)
     }
 
-    #[inline]
-    fn join_thread(&mut self, joined_thread_id: ThreadId) -> InterpResult<'tcx> {
+    /// Mark that the active thread tries to join the thread with `joined_thread_id`.
+    ///
+    /// When the join is successful (immediately, or as soon as the joined thread finishes), `success_retval` will be written to `return_dest`.
+    fn join_thread(
+        &mut self,
+        joined_thread_id: ThreadId,
+        success_retval: Scalar,
+        return_dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        this.machine.threads.join_thread(joined_thread_id, &mut this.machine.data_race)?;
+        let thread_mgr = &mut this.machine.threads;
+        if thread_mgr.threads[joined_thread_id].join_status == ThreadJoinStatus::Detached {
+            // On Windows this corresponds to joining on a closed handle.
+            throw_ub_format!("trying to join a detached thread");
+        }
+
+        fn after_join<'tcx>(
+            this: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
+            joined_thread_id: ThreadId,
+            success_retval: Scalar,
+            return_dest: &MPlaceTy<'tcx>,
+        ) -> InterpResult<'tcx> {
+            let threads = &this.machine.threads;
+            match &mut this.machine.data_race {
+                GlobalDataRaceHandler::None => {}
+                GlobalDataRaceHandler::Vclocks(data_race) =>
+                    data_race.thread_joined(threads, joined_thread_id),
+                GlobalDataRaceHandler::Genmc(genmc_ctx) =>
+                    genmc_ctx.handle_thread_join(threads.active_thread, joined_thread_id)?,
+            }
+            this.write_scalar(success_retval, return_dest)?;
+            interp_ok(())
+        }
+
+        // Mark the joined thread as being joined so that we detect if other
+        // threads try to join it.
+        thread_mgr.threads[joined_thread_id].join_status = ThreadJoinStatus::Joined;
+        if !thread_mgr.threads[joined_thread_id].state.is_terminated() {
+            trace!(
+                "{:?} blocked on {:?} when trying to join",
+                thread_mgr.active_thread, joined_thread_id
+            );
+            // The joined thread is still running, we need to wait for it.
+            // Once we get unblocked, perform the appropriate synchronization and write the return value.
+            let dest = return_dest.clone();
+            thread_mgr.block_thread(
+                BlockReason::Join(joined_thread_id),
+                None,
+                callback!(
+                    @capture<'tcx> {
+                        joined_thread_id: ThreadId,
+                        dest: MPlaceTy<'tcx>,
+                        success_retval: Scalar,
+                    }
+                    |this, unblock: UnblockKind| {
+                        assert_eq!(unblock, UnblockKind::Ready);
+                        after_join(this, joined_thread_id, success_retval, &dest)
+                    }
+                ),
+            );
+        } else {
+            // The thread has already terminated - establish happens-before and write the return value.
+            after_join(this, joined_thread_id, success_retval, return_dest)?;
+        }
         interp_ok(())
     }
 
-    #[inline]
-    fn join_thread_exclusive(&mut self, joined_thread_id: ThreadId) -> InterpResult<'tcx> {
+    /// Mark that the active thread tries to exclusively join the thread with `joined_thread_id`.
+    /// If the thread is already joined by another thread, it will throw UB.
+    ///
+    /// When the join is successful (immediately, or as soon as the joined thread finishes), `success_retval` will be written to `return_dest`.
+    fn join_thread_exclusive(
+        &mut self,
+        joined_thread_id: ThreadId,
+        success_retval: Scalar,
+        return_dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        this.machine
-            .threads
-            .join_thread_exclusive(joined_thread_id, &mut this.machine.data_race)?;
-        interp_ok(())
+        let threads = &this.machine.threads.threads;
+        if threads[joined_thread_id].join_status == ThreadJoinStatus::Joined {
+            throw_ub_format!("trying to join an already joined thread");
+        }
+
+        if joined_thread_id == this.machine.threads.active_thread {
+            throw_ub_format!("trying to join itself");
+        }
+
+        // Sanity check `join_status`.
+        assert!(
+            threads
+                .iter()
+                .all(|thread| { !thread.state.is_blocked_on(BlockReason::Join(joined_thread_id)) }),
+            "this thread already has threads waiting for its termination"
+        );
+
+        this.join_thread(joined_thread_id, success_retval, return_dest)
     }
 
     #[inline]
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 54a7c1407ea..9ecbd31c5b9 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -132,7 +132,9 @@ pub enum NonHaltingDiagnostic {
     Int2Ptr {
         details: bool,
     },
-    NativeCallSharedMem,
+    NativeCallSharedMem {
+        tracing: bool,
+    },
     WeakMemoryOutdatedLoad {
         ptr: Pointer,
     },
@@ -627,7 +629,7 @@ impl<'tcx> MiriMachine<'tcx> {
             RejectedIsolatedOp(_) =>
                 ("operation rejected by isolation".to_string(), DiagLevel::Warning),
             Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning),
-            NativeCallSharedMem =>
+            NativeCallSharedMem { .. } =>
                 ("sharing memory with a native function".to_string(), DiagLevel::Warning),
             ExternTypeReborrow =>
                 ("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning),
@@ -663,7 +665,8 @@ impl<'tcx> MiriMachine<'tcx> {
             ProgressReport { .. } =>
                 format!("progress report: current operation being executed is here"),
             Int2Ptr { .. } => format!("integer-to-pointer cast"),
-            NativeCallSharedMem => format!("sharing memory with a native function called via FFI"),
+            NativeCallSharedMem { .. } =>
+                format!("sharing memory with a native function called via FFI"),
             WeakMemoryOutdatedLoad { ptr } =>
                 format!("weak memory emulation: outdated value returned from load at {ptr}"),
             ExternTypeReborrow =>
@@ -709,22 +712,41 @@ impl<'tcx> MiriMachine<'tcx> {
                 }
                 v
             }
-            NativeCallSharedMem => {
-                vec![
-                    note!(
-                        "when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory"
-                    ),
-                    note!(
-                        "in particular, Miri assumes that the native call initializes all memory it has access to"
-                    ),
-                    note!(
-                        "Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
-                    ),
-                    note!(
-                        "what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
-                    ),
-                ]
-            }
+            NativeCallSharedMem { tracing } =>
+                if *tracing {
+                    vec![
+                        note!(
+                            "when memory is shared with a native function call, Miri can only track initialisation and provenance on a best-effort basis"
+                        ),
+                        note!(
+                            "in particular, Miri assumes that the native call initializes all memory it has written to"
+                        ),
+                        note!(
+                            "Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
+                        ),
+                        note!(
+                            "what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
+                        ),
+                        note!(
+                            "tracing memory accesses in native code is not yet fully implemented, so there can be further imprecisions beyond what is documented here"
+                        ),
+                    ]
+                } else {
+                    vec![
+                        note!(
+                            "when memory is shared with a native function call, Miri stops tracking initialization and provenance for that memory"
+                        ),
+                        note!(
+                            "in particular, Miri assumes that the native call initializes all memory it has access to"
+                        ),
+                        note!(
+                            "Miri also assumes that any part of this memory may be a pointer that is permitted to point to arbitrary exposed memory"
+                        ),
+                        note!(
+                            "what this means is that Miri will easily miss Undefined Behavior related to incorrect usage of this shared memory, so you should not take a clean Miri run as a signal that your FFI code is UB-free"
+                        ),
+                    ]
+                },
             ExternTypeReborrow => {
                 assert!(self.borrow_tracker.as_ref().is_some_and(|b| {
                     matches!(
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 04fe08b30ee..44612dae1ee 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -150,6 +150,8 @@ pub struct MiriConfig {
     pub retag_fields: RetagFields,
     /// The location of the shared object files to load when calling external functions
     pub native_lib: Vec<PathBuf>,
+    /// Whether to enable the new native lib tracing system.
+    pub native_lib_enable_tracing: bool,
     /// Run a garbage collector for BorTags every N basic blocks.
     pub gc_interval: u32,
     /// The number of CPUs to be reported by miri.
@@ -199,6 +201,7 @@ impl Default for MiriConfig {
             report_progress: None,
             retag_fields: RetagFields::Yes,
             native_lib: vec![],
+            native_lib_enable_tracing: false,
             gc_interval: 10_000,
             num_cpus: 1,
             page_size: None,
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index ec77a162cdb..ed1851a19ae 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let [f] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f32()?;
 
-                let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{
+                let res = fixed_float_value(this, intrinsic_name, &[f]).unwrap_or_else(|| {
                     // Using host floats (but it's fine, these operations do not have
                     // guaranteed precision).
                     let host = f.to_host();
@@ -235,7 +235,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let [f] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f64()?;
 
-                let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{
+                let res = fixed_float_value(this, intrinsic_name, &[f]).unwrap_or_else(|| {
                     // Using host floats (but it's fine, these operations do not have
                     // guaranteed precision).
                     let host = f.to_host();
@@ -312,7 +312,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let f1 = this.read_scalar(f1)?.to_f32()?;
                 let f2 = this.read_scalar(f2)?.to_f32()?;
 
-                let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
+                let res = fixed_float_value(this, intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
                     // Using host floats (but it's fine, this operation does not have guaranteed precision).
                     let res = f1.to_host().powf(f2.to_host()).to_soft();
 
@@ -330,7 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let f1 = this.read_scalar(f1)?.to_f64()?;
                 let f2 = this.read_scalar(f2)?.to_f64()?;
 
-                let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
+                let res = fixed_float_value(this, intrinsic_name, &[f1, f2]).unwrap_or_else(|| {
                     // Using host floats (but it's fine, this operation does not have guaranteed precision).
                     let res = f1.to_host().powf(f2.to_host()).to_soft();
 
@@ -349,7 +349,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let f = this.read_scalar(f)?.to_f32()?;
                 let i = this.read_scalar(i)?.to_i32()?;
 
-                let res = fixed_powi_float_value(f, i).unwrap_or_else(|| {
+                let res = fixed_powi_float_value(this, f, i).unwrap_or_else(|| {
                     // Using host floats (but it's fine, this operation does not have guaranteed precision).
                     let res = f.to_host().powi(i).to_soft();
 
@@ -367,7 +367,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let f = this.read_scalar(f)?.to_f64()?;
                 let i = this.read_scalar(i)?.to_i32()?;
 
-                let res = fixed_powi_float_value(f, i).unwrap_or_else(|| {
+                let res = fixed_powi_float_value(this, f, i).unwrap_or_else(|| {
                     // Using host floats (but it's fine, this operation does not have guaranteed precision).
                     let res = f.to_host().powi(i).to_soft();
 
@@ -496,52 +496,88 @@ fn apply_random_float_error_to_imm<'tcx>(
 /// - logf32, logf64, log2f32, log2f64, log10f32, log10f64
 /// - powf32, powf64
 ///
+/// # Return
+///
 /// Returns `Some(output)` if the `intrinsic` results in a defined fixed `output` specified in the C standard
 /// (specifically, C23 annex F.10)  when given `args` as arguments. Outputs that are unaffected by a relative error
 /// (such as INF and zero) are not handled here, they are assumed to be handled by the underlying
 /// implementation. Returns `None` if no specific value is guaranteed.
+///
+/// # Note
+///
+/// For `powf*` operations of the form:
+///
+/// - `(SNaN)^(±0)`
+/// - `1^(SNaN)`
+///
+/// The result is implementation-defined:
+/// - musl returns for both `1.0`
+/// - glibc returns for both `NaN`
+///
+/// This discrepancy exists because SNaN handling is not consistently defined across platforms,
+/// and the C standard leaves behavior for SNaNs unspecified.
+///
+/// Miri chooses to adhere to both implementations and returns either one of them non-deterministically.
 fn fixed_float_value<S: Semantics>(
+    ecx: &mut MiriInterpCx<'_>,
     intrinsic_name: &str,
     args: &[IeeeFloat<S>],
 ) -> Option<IeeeFloat<S>> {
     let one = IeeeFloat::<S>::one();
-    match (intrinsic_name, args) {
+    Some(match (intrinsic_name, args) {
         // cos(+- 0) = 1
-        ("cosf32" | "cosf64", [input]) if input.is_zero() => Some(one),
+        ("cosf32" | "cosf64", [input]) if input.is_zero() => one,
 
         // e^0 = 1
-        ("expf32" | "expf64" | "exp2f32" | "exp2f64", [input]) if input.is_zero() => Some(one),
-
-        // 1^y = 1 for any y, even a NaN.
-        ("powf32" | "powf64", [base, _]) if *base == one => Some(one),
+        ("expf32" | "expf64" | "exp2f32" | "exp2f64", [input]) if input.is_zero() => one,
 
         // (-1)^(±INF) = 1
-        ("powf32" | "powf64", [base, exp]) if *base == -one && exp.is_infinite() => Some(one),
+        ("powf32" | "powf64", [base, exp]) if *base == -one && exp.is_infinite() => one,
+
+        // 1^y = 1 for any y, even a NaN
+        ("powf32" | "powf64", [base, exp]) if *base == one => {
+            let rng = ecx.machine.rng.get_mut();
+            // SNaN exponents get special treatment: they might return 1, or a NaN.
+            let return_nan = exp.is_signaling() && ecx.machine.float_nondet && rng.random();
+            // Handle both the musl and glibc cases non-deterministically.
+            if return_nan { ecx.generate_nan(args) } else { one }
+        }
 
-        // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate
-        // the NaN. We should return either 1 or the NaN non-deterministically here.
-        // But for now, just handle them all the same.
         // x^(±0) = 1 for any x, even a NaN
-        ("powf32" | "powf64", [_, exp]) if exp.is_zero() => Some(one),
+        ("powf32" | "powf64", [base, exp]) if exp.is_zero() => {
+            let rng = ecx.machine.rng.get_mut();
+            // SNaN bases get special treatment: they might return 1, or a NaN.
+            let return_nan = base.is_signaling() && ecx.machine.float_nondet && rng.random();
+            // Handle both the musl and glibc cases non-deterministically.
+            if return_nan { ecx.generate_nan(args) } else { one }
+        }
 
-        // There are a lot of cases for fixed outputs according to the C Standard, but these are mainly INF or zero
-        // which are not affected by the applied error.
-        _ => None,
-    }
+        // There are a lot of cases for fixed outputs according to the C Standard, but these are
+        // mainly INF or zero which are not affected by the applied error.
+        _ => return None,
+    })
 }
 
-/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the C standard
-/// (specifically, C23 annex F.10.4.6) when doing `base^exp`. Otherwise, returns `None`.
-fn fixed_powi_float_value<S: Semantics>(base: IeeeFloat<S>, exp: i32) -> Option<IeeeFloat<S>> {
-    match (base.category(), exp) {
-        // x^0 = 1, if x is not a Signaling NaN
-        // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate
-        // the NaN. We should return either 1 or the NaN non-deterministically here.
-        // But for now, just handle them all the same.
-        (_, 0) => Some(IeeeFloat::<S>::one()),
-
-        _ => None,
-    }
+/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the
+/// C standard (specifically, C23 annex F.10.4.6) when doing `base^exp`. Otherwise, returns `None`.
+fn fixed_powi_float_value<S: Semantics>(
+    ecx: &mut MiriInterpCx<'_>,
+    base: IeeeFloat<S>,
+    exp: i32,
+) -> Option<IeeeFloat<S>> {
+    Some(match exp {
+        0 => {
+            let one = IeeeFloat::<S>::one();
+            let rng = ecx.machine.rng.get_mut();
+            let return_nan = ecx.machine.float_nondet && rng.random() && base.is_signaling();
+            // For SNaN treatment, we are consistent with `powf`above.
+            // (We wouldn't have two, unlike powf all implementations seem to agree for powi,
+            // but for now we are maximally conservative.)
+            if return_nan { ecx.generate_nan(&[base]) } else { one }
+        }
+
+        _ => return None,
+    })
 }
 
 /// Given an floating-point operation and a floating-point value, clamps the result to the output
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index 52224f33c73..e63992aa95f 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -36,6 +36,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "ceil"
             | "floor"
             | "round"
+            | "round_ties_even"
             | "trunc"
             | "fsqrt"
             | "fsin"
@@ -71,6 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     "ceil" => Op::Round(rustc_apfloat::Round::TowardPositive),
                     "floor" => Op::Round(rustc_apfloat::Round::TowardNegative),
                     "round" => Op::Round(rustc_apfloat::Round::NearestTiesToAway),
+                    "round_ties_even" => Op::Round(rustc_apfloat::Round::NearestTiesToEven),
                     "trunc" => Op::Round(rustc_apfloat::Round::TowardZero),
                     "ctlz" => Op::Numeric(sym::ctlz),
                     "ctpop" => Op::Numeric(sym::ctpop),
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index ea56582ee48..00f26a37f71 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -10,6 +10,7 @@
 #![feature(variant_count)]
 #![feature(yeet_expr)]
 #![feature(nonzero_ops)]
+#![cfg_attr(bootstrap, feature(nonnull_provenance))]
 #![feature(strict_overflow_ops)]
 #![feature(pointer_is_aligned_to)]
 #![feature(ptr_metadata)]
@@ -99,6 +100,11 @@ pub use rustc_const_eval::interpret::{self, AllocMap, Provenance as _};
 use rustc_middle::{bug, span_bug};
 use tracing::{info, trace};
 
+//#[cfg(target_os = "linux")]
+//pub mod native_lib {
+//    pub use crate::shims::{init_sv, register_retcode_sv};
+//}
+
 // Type aliases that set the provenance parameter.
 pub type Pointer = interpret::Pointer<Option<machine::Provenance>>;
 pub type StrictPointer = interpret::Pointer<machine::Provenance>;
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index b4d7db34efa..3a748c4c687 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1056,7 +1056,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
             // What's the offset between us and the promised alignment?
             let distance = offset.bytes().wrapping_sub(promised_offset.bytes());
             // That must also be aligned.
-            if distance % align.bytes() == 0 {
+            if distance.is_multiple_of(align.bytes()) {
                 // All looking good!
                 None
             } else {
@@ -1612,7 +1612,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         ecx.machine.since_gc += 1;
         // 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 {
+            if ecx.machine.basic_block_count.is_multiple_of(u64::from(report_progress)) {
                 ecx.emit_diagnostic(NonHaltingDiagnostic::ProgressReport {
                     block_count: ecx.machine.basic_block_count,
                 });
diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs
index b498551ace3..f09fc546b3e 100644
--- a/src/tools/miri/src/shims/mod.rs
+++ b/src/tools/miri/src/shims/mod.rs
@@ -21,6 +21,8 @@ pub mod time;
 pub mod tls;
 
 pub use self::files::FdTable;
+//#[cfg(target_os = "linux")]
+//pub use self::native_lib::trace::{init_sv, register_retcode_sv};
 pub use self::unix::{DirTable, EpollInterestTable};
 
 /// What needs to be done after emulating an item (a shim or an intrinsic) is done.
diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib/mod.rs
index 030c2e36721..9c659f65e50 100644
--- a/src/tools/miri/src/shims/native_lib.rs
+++ b/src/tools/miri/src/shims/native_lib/mod.rs
@@ -1,4 +1,9 @@
 //! Implements calling functions from a native library.
+
+// FIXME: disabled since it fails to build on many targets.
+//#[cfg(target_os = "linux")]
+//pub mod trace;
+
 use std::ops::Deref;
 
 use libffi::high::call as ffi;
@@ -8,8 +13,15 @@ use rustc_middle::mir::interpret::Pointer;
 use rustc_middle::ty::{self as ty, IntTy, UintTy};
 use rustc_span::Symbol;
 
+//#[cfg(target_os = "linux")]
+//use self::trace::Supervisor;
 use crate::*;
 
+//#[cfg(target_os = "linux")]
+//type CallResult<'tcx> = InterpResult<'tcx, (ImmTy<'tcx>, Option<self::trace::messages::MemEvents>)>;
+//#[cfg(not(target_os = "linux"))]
+type CallResult<'tcx> = InterpResult<'tcx, (ImmTy<'tcx>, Option<!>)>;
+
 impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
 trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     /// Call native host function and return the output as an immediate.
@@ -19,71 +31,93 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         dest: &MPlaceTy<'tcx>,
         ptr: CodePtr,
         libffi_args: Vec<libffi::high::Arg<'a>>,
-    ) -> InterpResult<'tcx, ImmTy<'tcx>> {
+    ) -> CallResult<'tcx> {
         let this = self.eval_context_mut();
+        //#[cfg(target_os = "linux")]
+        //let alloc = this.machine.allocator.as_ref().unwrap();
+
+        // SAFETY: We don't touch the machine memory past this point.
+        //#[cfg(target_os = "linux")]
+        //let (guard, stack_ptr) = unsafe { Supervisor::start_ffi(alloc) };
 
         // Call the function (`ptr`) with arguments `libffi_args`, and obtain the return value
         // as the specified primitive integer type
-        let scalar = match dest.layout.ty.kind() {
-            // ints
-            ty::Int(IntTy::I8) => {
-                // Unsafe because of the call to native code.
-                // Because this is calling a C function it is not necessarily sound,
-                // but there is no way around this and we've checked as much as we can.
-                let x = unsafe { ffi::call::<i8>(ptr, libffi_args.as_slice()) };
-                Scalar::from_i8(x)
-            }
-            ty::Int(IntTy::I16) => {
-                let x = unsafe { ffi::call::<i16>(ptr, libffi_args.as_slice()) };
-                Scalar::from_i16(x)
-            }
-            ty::Int(IntTy::I32) => {
-                let x = unsafe { ffi::call::<i32>(ptr, libffi_args.as_slice()) };
-                Scalar::from_i32(x)
-            }
-            ty::Int(IntTy::I64) => {
-                let x = unsafe { ffi::call::<i64>(ptr, libffi_args.as_slice()) };
-                Scalar::from_i64(x)
-            }
-            ty::Int(IntTy::Isize) => {
-                let x = unsafe { ffi::call::<isize>(ptr, libffi_args.as_slice()) };
-                Scalar::from_target_isize(x.try_into().unwrap(), this)
-            }
-            // uints
-            ty::Uint(UintTy::U8) => {
-                let x = unsafe { ffi::call::<u8>(ptr, libffi_args.as_slice()) };
-                Scalar::from_u8(x)
-            }
-            ty::Uint(UintTy::U16) => {
-                let x = unsafe { ffi::call::<u16>(ptr, libffi_args.as_slice()) };
-                Scalar::from_u16(x)
-            }
-            ty::Uint(UintTy::U32) => {
-                let x = unsafe { ffi::call::<u32>(ptr, libffi_args.as_slice()) };
-                Scalar::from_u32(x)
-            }
-            ty::Uint(UintTy::U64) => {
-                let x = unsafe { ffi::call::<u64>(ptr, libffi_args.as_slice()) };
-                Scalar::from_u64(x)
-            }
-            ty::Uint(UintTy::Usize) => {
-                let x = unsafe { ffi::call::<usize>(ptr, libffi_args.as_slice()) };
-                Scalar::from_target_usize(x.try_into().unwrap(), this)
-            }
-            // Functions with no declared return type (i.e., the default return)
-            // have the output_type `Tuple([])`.
-            ty::Tuple(t_list) if (*t_list).deref().is_empty() => {
-                unsafe { ffi::call::<()>(ptr, libffi_args.as_slice()) };
-                return interp_ok(ImmTy::uninit(dest.layout));
-            }
-            ty::RawPtr(..) => {
-                let x = unsafe { ffi::call::<*const ()>(ptr, libffi_args.as_slice()) };
-                let ptr = Pointer::new(Provenance::Wildcard, Size::from_bytes(x.addr()));
-                Scalar::from_pointer(ptr, this)
-            }
-            _ => throw_unsup_format!("unsupported return type for native call: {:?}", link_name),
+        let res = 'res: {
+            let scalar = match dest.layout.ty.kind() {
+                // ints
+                ty::Int(IntTy::I8) => {
+                    // Unsafe because of the call to native code.
+                    // Because this is calling a C function it is not necessarily sound,
+                    // but there is no way around this and we've checked as much as we can.
+                    let x = unsafe { ffi::call::<i8>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_i8(x)
+                }
+                ty::Int(IntTy::I16) => {
+                    let x = unsafe { ffi::call::<i16>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_i16(x)
+                }
+                ty::Int(IntTy::I32) => {
+                    let x = unsafe { ffi::call::<i32>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_i32(x)
+                }
+                ty::Int(IntTy::I64) => {
+                    let x = unsafe { ffi::call::<i64>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_i64(x)
+                }
+                ty::Int(IntTy::Isize) => {
+                    let x = unsafe { ffi::call::<isize>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_target_isize(x.try_into().unwrap(), this)
+                }
+                // uints
+                ty::Uint(UintTy::U8) => {
+                    let x = unsafe { ffi::call::<u8>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_u8(x)
+                }
+                ty::Uint(UintTy::U16) => {
+                    let x = unsafe { ffi::call::<u16>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_u16(x)
+                }
+                ty::Uint(UintTy::U32) => {
+                    let x = unsafe { ffi::call::<u32>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_u32(x)
+                }
+                ty::Uint(UintTy::U64) => {
+                    let x = unsafe { ffi::call::<u64>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_u64(x)
+                }
+                ty::Uint(UintTy::Usize) => {
+                    let x = unsafe { ffi::call::<usize>(ptr, libffi_args.as_slice()) };
+                    Scalar::from_target_usize(x.try_into().unwrap(), this)
+                }
+                // Functions with no declared return type (i.e., the default return)
+                // have the output_type `Tuple([])`.
+                ty::Tuple(t_list) if (*t_list).deref().is_empty() => {
+                    unsafe { ffi::call::<()>(ptr, libffi_args.as_slice()) };
+                    break 'res interp_ok(ImmTy::uninit(dest.layout));
+                }
+                ty::RawPtr(..) => {
+                    let x = unsafe { ffi::call::<*const ()>(ptr, libffi_args.as_slice()) };
+                    let ptr = Pointer::new(Provenance::Wildcard, Size::from_bytes(x.addr()));
+                    Scalar::from_pointer(ptr, this)
+                }
+                _ =>
+                    break 'res Err(err_unsup_format!(
+                        "unsupported return type for native call: {:?}",
+                        link_name
+                    ))
+                    .into(),
+            };
+            interp_ok(ImmTy::from_scalar(scalar, dest.layout))
         };
-        interp_ok(ImmTy::from_scalar(scalar, dest.layout))
+
+        // SAFETY: We got the guard and stack pointer from start_ffi, and
+        // the allocator is the same
+        //#[cfg(target_os = "linux")]
+        //let events = unsafe { Supervisor::end_ffi(alloc, guard, stack_ptr) };
+        //#[cfg(not(target_os = "linux"))]
+        let events = None;
+
+        interp_ok((res?, events))
     }
 
     /// Get the pointer to the function of the specified name in the shared object file,
@@ -179,7 +213,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // The first time this happens, print a warning.
                 if !this.machine.native_call_mem_warned.replace(true) {
                     // Newly set, so first time we get here.
-                    this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
+                    this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem {
+                        //#[cfg(target_os = "linux")]
+                        //tracing: self::trace::Supervisor::is_enabled(),
+                        //#[cfg(not(target_os = "linux"))]
+                        tracing: false,
+                    });
                 }
 
                 this.expose_provenance(prov)?;
@@ -196,7 +235,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             .collect::<Vec<libffi::high::Arg<'_>>>();
 
         // Call the function and store output, depending on return type in the function signature.
-        let ret = this.call_native_with_args(link_name, dest, code_ptr, libffi_args)?;
+        let (ret, maybe_memevents) =
+            this.call_native_with_args(link_name, dest, code_ptr, libffi_args)?;
+
+        if cfg!(target_os = "linux")
+            && let Some(events) = maybe_memevents
+        {
+            trace!("Registered FFI events:\n{events:#0x?}");
+        }
+
         this.write_immediate(*ret, dest)?;
         interp_ok(true)
     }
diff --git a/src/tools/miri/src/shims/native_lib/trace/child.rs b/src/tools/miri/src/shims/native_lib/trace/child.rs
new file mode 100644
index 00000000000..4961e875c77
--- /dev/null
+++ b/src/tools/miri/src/shims/native_lib/trace/child.rs
@@ -0,0 +1,251 @@
+use std::cell::RefCell;
+use std::rc::Rc;
+
+use ipc_channel::ipc;
+use nix::sys::{ptrace, signal};
+use nix::unistd;
+
+use super::CALLBACK_STACK_SIZE;
+use super::messages::{Confirmation, MemEvents, StartFfiInfo, TraceRequest};
+use super::parent::{ChildListener, sv_loop};
+use crate::alloc::isolated_alloc::IsolatedAlloc;
+
+static SUPERVISOR: std::sync::Mutex<Option<Supervisor>> = std::sync::Mutex::new(None);
+
+/// The main means of communication between the child and parent process,
+/// allowing the former to send requests and get info from the latter.
+pub struct Supervisor {
+    /// Sender for FFI-mode-related requests.
+    message_tx: ipc::IpcSender<TraceRequest>,
+    /// Used for synchronisation, allowing us to receive confirmation that the
+    /// parent process has handled the request from `message_tx`.
+    confirm_rx: ipc::IpcReceiver<Confirmation>,
+    /// Receiver for memory acceses that ocurred during the FFI call.
+    event_rx: ipc::IpcReceiver<MemEvents>,
+}
+
+/// Marker representing that an error occurred during creation of the supervisor.
+#[derive(Debug)]
+pub struct SvInitError;
+
+impl Supervisor {
+    /// Returns `true` if the supervisor process exists, and `false` otherwise.
+    pub fn is_enabled() -> bool {
+        SUPERVISOR.lock().unwrap().is_some()
+    }
+
+    /// Begins preparations for doing an FFI call. This should be called at
+    /// the last possible moment before entering said call. `alloc` points to
+    /// the allocator which handed out the memory used for this machine.
+    ///
+    /// As this locks the supervisor via a mutex, no other threads may enter FFI
+    /// until this one returns and its guard is dropped via `end_ffi`. The
+    /// pointer returned should be passed to `end_ffi` to avoid a memory leak.
+    ///
+    /// SAFETY: The resulting guard must be dropped *via `end_ffi`* immediately
+    /// after the desired call has concluded.
+    pub unsafe fn start_ffi(
+        alloc: &Rc<RefCell<IsolatedAlloc>>,
+    ) -> (std::sync::MutexGuard<'static, Option<Supervisor>>, Option<*mut [u8; CALLBACK_STACK_SIZE]>)
+    {
+        let mut sv_guard = SUPERVISOR.lock().unwrap();
+        // If the supervisor is not initialised for whatever reason, fast-fail.
+        // This might be desired behaviour, as even on platforms where ptracing
+        // is not implemented it enables us to enforce that only one FFI call
+        // happens at a time.
+        let Some(sv) = sv_guard.take() else {
+            return (sv_guard, None);
+        };
+
+        // Get pointers to all the pages the supervisor must allow accesses in
+        // and prepare the callback stack.
+        let page_ptrs = alloc.borrow().pages();
+        let raw_stack_ptr: *mut [u8; CALLBACK_STACK_SIZE] =
+            Box::leak(Box::new([0u8; CALLBACK_STACK_SIZE])).as_mut_ptr().cast();
+        let stack_ptr = raw_stack_ptr.expose_provenance();
+        let start_info = StartFfiInfo { page_ptrs, stack_ptr };
+
+        // SAFETY: We do not access machine memory past this point until the
+        // supervisor is ready to allow it.
+        unsafe {
+            if alloc.borrow_mut().prepare_ffi().is_err() {
+                // Don't mess up unwinding by maybe leaving the memory partly protected
+                alloc.borrow_mut().unprep_ffi();
+                panic!("Cannot protect memory for FFI call!");
+            }
+        }
+
+        // Send over the info.
+        // NB: if we do not wait to receive a blank confirmation response, it is
+        // possible that the supervisor is alerted of the SIGSTOP *before* it has
+        // actually received the start_info, thus deadlocking! This way, we can
+        // enforce an ordering for these events.
+        sv.message_tx.send(TraceRequest::StartFfi(start_info)).unwrap();
+        sv.confirm_rx.recv().unwrap();
+        *sv_guard = Some(sv);
+        // We need to be stopped for the supervisor to be able to make certain
+        // modifications to our memory - simply waiting on the recv() doesn't
+        // count.
+        signal::raise(signal::SIGSTOP).unwrap();
+        (sv_guard, Some(raw_stack_ptr))
+    }
+
+    /// Undoes FFI-related preparations, allowing Miri to continue as normal, then
+    /// gets the memory accesses and changes performed during the FFI call. Note
+    /// that this may include some spurious accesses done by `libffi` itself in
+    /// the process of executing the function call.
+    ///
+    /// SAFETY: The `sv_guard` and `raw_stack_ptr` passed must be the same ones
+    /// received by a prior call to `start_ffi`, and the allocator must be the
+    /// one passed to it also.
+    pub unsafe fn end_ffi(
+        alloc: &Rc<RefCell<IsolatedAlloc>>,
+        mut sv_guard: std::sync::MutexGuard<'static, Option<Supervisor>>,
+        raw_stack_ptr: Option<*mut [u8; CALLBACK_STACK_SIZE]>,
+    ) -> Option<MemEvents> {
+        // We can't use IPC channels here to signal that FFI mode has ended,
+        // since they might allocate memory which could get us stuck in a SIGTRAP
+        // with no easy way out! While this could be worked around, it is much
+        // simpler and more robust to simply use the signals which are left for
+        // arbitrary usage. Since this will block until we are continued by the
+        // supervisor, we can assume past this point that everything is back to
+        // normal.
+        signal::raise(signal::SIGUSR1).unwrap();
+
+        // This is safe! It just sets memory to normal expected permissions.
+        alloc.borrow_mut().unprep_ffi();
+
+        // If this is `None`, then `raw_stack_ptr` is None and does not need to
+        // be deallocated (and there's no need to worry about the guard, since
+        // it contains nothing).
+        let sv = sv_guard.take()?;
+        // SAFETY: Caller upholds that this pointer was allocated as a box with
+        // this type.
+        unsafe {
+            drop(Box::from_raw(raw_stack_ptr.unwrap()));
+        }
+        // On the off-chance something really weird happens, don't block forever.
+        let ret = sv
+            .event_rx
+            .try_recv_timeout(std::time::Duration::from_secs(5))
+            .map_err(|e| {
+                match e {
+                    ipc::TryRecvError::IpcError(_) => (),
+                    ipc::TryRecvError::Empty =>
+                        eprintln!("Waiting for accesses from supervisor timed out!"),
+                }
+            })
+            .ok();
+        // Do *not* leave the supervisor empty, or else we might get another fork...
+        *sv_guard = Some(sv);
+        ret
+    }
+}
+
+/// Initialises the supervisor process. If this function errors, then the
+/// supervisor process could not be created successfully; else, the caller
+/// is now the child process and can communicate via `start_ffi`/`end_ffi`,
+/// receiving back events through `get_events`.
+///
+/// # Safety
+/// The invariants for `fork()` must be upheld by the caller.
+pub unsafe fn init_sv() -> Result<(), SvInitError> {
+    // FIXME: Much of this could be reimplemented via the mitosis crate if we upstream the
+    // relevant missing bits.
+
+    // On Linux, this will check whether ptrace is fully disabled by the Yama module.
+    // If Yama isn't running or we're not on Linux, we'll still error later, but
+    // this saves a very expensive fork call.
+    let ptrace_status = std::fs::read_to_string("/proc/sys/kernel/yama/ptrace_scope");
+    if let Ok(stat) = ptrace_status {
+        if let Some(stat) = stat.chars().next() {
+            // Fast-error if ptrace is fully disabled on the system.
+            if stat == '3' {
+                return Err(SvInitError);
+            }
+        }
+    }
+
+    // Initialise the supervisor if it isn't already, placing it into SUPERVISOR.
+    let mut lock = SUPERVISOR.lock().unwrap();
+    if lock.is_some() {
+        return Ok(());
+    }
+
+    // Prepare the IPC channels we need.
+    let (message_tx, message_rx) = ipc::channel().unwrap();
+    let (confirm_tx, confirm_rx) = ipc::channel().unwrap();
+    let (event_tx, event_rx) = ipc::channel().unwrap();
+    // SAFETY: Calling sysconf(_SC_PAGESIZE) is always safe and cannot error.
+    let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) }.try_into().unwrap();
+    super::parent::PAGE_SIZE.store(page_size, std::sync::atomic::Ordering::Relaxed);
+
+    unsafe {
+        // TODO: Maybe use clone3() instead for better signalling of when the child exits?
+        // SAFETY: Caller upholds that only one thread exists.
+        match unistd::fork().unwrap() {
+            unistd::ForkResult::Parent { child } => {
+                // If somehow another thread does exist, prevent it from accessing the lock
+                // and thus breaking our safety invariants.
+                std::mem::forget(lock);
+                // The child process is free to unwind, so we won't to avoid doubly freeing
+                // system resources.
+                let init = std::panic::catch_unwind(|| {
+                    let listener =
+                        ChildListener { message_rx, attached: false, override_retcode: None };
+                    // Trace as many things as possible, to be able to handle them as needed.
+                    let options = ptrace::Options::PTRACE_O_TRACESYSGOOD
+                        | ptrace::Options::PTRACE_O_TRACECLONE
+                        | ptrace::Options::PTRACE_O_TRACEFORK;
+                    // Attach to the child process without stopping it.
+                    match ptrace::seize(child, options) {
+                        // Ptrace works :D
+                        Ok(_) => {
+                            let code = sv_loop(listener, child, event_tx, confirm_tx).unwrap_err();
+                            // If a return code of 0 is not explicitly given, assume something went
+                            // wrong and return 1.
+                            std::process::exit(code.0.unwrap_or(1))
+                        }
+                        // Ptrace does not work and we failed to catch that.
+                        Err(_) => {
+                            // If we can't ptrace, Miri continues being the parent.
+                            signal::kill(child, signal::SIGKILL).unwrap();
+                            SvInitError
+                        }
+                    }
+                });
+                match init {
+                    // The "Ok" case means that we couldn't ptrace.
+                    Ok(e) => return Err(e),
+                    Err(p) => {
+                        eprintln!("Supervisor process panicked!\n{p:?}");
+                        std::process::exit(1);
+                    }
+                }
+            }
+            unistd::ForkResult::Child => {
+                // Make sure we never get orphaned and stuck in SIGSTOP or similar
+                // SAFETY: prctl PR_SET_PDEATHSIG is always safe to call.
+                let ret = libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGTERM);
+                assert_eq!(ret, 0);
+                // First make sure the parent succeeded with ptracing us!
+                signal::raise(signal::SIGSTOP).unwrap();
+                // If we're the child process, save the supervisor info.
+                *lock = Some(Supervisor { message_tx, confirm_rx, event_rx });
+            }
+        }
+    }
+    Ok(())
+}
+
+/// Instruct the supervisor process to return a particular code. Useful if for
+/// whatever reason this code fails to be intercepted normally. In the case of
+/// `abort_if_errors()` used in `bin/miri.rs`, the return code is erroneously
+/// given as a 0 if this is not used.
+pub fn register_retcode_sv(code: i32) {
+    let mut sv_guard = SUPERVISOR.lock().unwrap();
+    if let Some(sv) = sv_guard.take() {
+        sv.message_tx.send(TraceRequest::OverrideRetcode(code)).unwrap();
+        *sv_guard = Some(sv);
+    }
+}
diff --git a/src/tools/miri/src/shims/native_lib/trace/messages.rs b/src/tools/miri/src/shims/native_lib/trace/messages.rs
new file mode 100644
index 00000000000..8a83dab5c09
--- /dev/null
+++ b/src/tools/miri/src/shims/native_lib/trace/messages.rs
@@ -0,0 +1,80 @@
+//! Houses the types that are directly sent across the IPC channels.
+//!
+//! The overall structure of a traced FFI call, from the child process's POV, is
+//! as follows:
+//! ```
+//! message_tx.send(TraceRequest::StartFfi);
+//! confirm_rx.recv();
+//! raise(SIGSTOP);
+//! /* do ffi call */
+//! raise(SIGUSR1); // morally equivalent to some kind of "TraceRequest::EndFfi"
+//! let events = event_rx.recv();
+//! ```
+//! `TraceRequest::OverrideRetcode` can be sent at any point in the above, including
+//! before or after all of them.
+//!
+//! NB: sending these events out of order, skipping steps, etc. will result in
+//! unspecified behaviour from the supervisor process, so use the abstractions
+//! in `super::child` (namely `start_ffi()` and `end_ffi()`) to handle this. It is
+//! trivially easy to cause a deadlock or crash by messing this up!
+
+use std::ops::Range;
+
+/// An IPC request sent by the child process to the parent.
+///
+/// The sender for this channel should live on the child process.
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
+pub enum TraceRequest {
+    /// Requests that tracing begins. Following this being sent, the child must
+    /// wait to receive a `Confirmation` on the respective channel and then
+    /// `raise(SIGSTOP)`.
+    ///
+    /// To avoid possible issues while allocating memory for IPC channels, ending
+    /// the tracing is instead done via `raise(SIGUSR1)`.
+    StartFfi(StartFfiInfo),
+    /// Manually overrides the code that the supervisor will return upon exiting.
+    /// Once set, it is permanent. This can be called again to change the value.
+    OverrideRetcode(i32),
+}
+
+/// Information needed to begin tracing.
+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
+pub struct StartFfiInfo {
+    /// A vector of page addresses. These should have been automatically obtained
+    /// with `IsolatedAlloc::pages` and prepared with `IsolatedAlloc::prepare_ffi`.
+    pub page_ptrs: Vec<usize>,
+    /// The address of an allocation that can serve as a temporary stack.
+    /// This should be a leaked `Box<[u8; CALLBACK_STACK_SIZE]>` cast to an int.
+    pub stack_ptr: usize,
+}
+
+/// A marker type confirming that the supervisor has received the request to begin
+/// tracing and is now waiting for a `SIGSTOP`.
+///
+/// The sender for this channel should live on the parent process.
+#[derive(serde::Serialize, serde::Deserialize, Debug)]
+pub struct Confirmation;
+
+/// The final results of an FFI trace, containing every relevant event detected
+/// by the tracer. Sent by the supervisor after receiving a `SIGUSR1` signal.
+///
+/// The sender for this channel should live on the parent process.
+#[derive(serde::Serialize, serde::Deserialize, Debug)]
+pub struct MemEvents {
+    /// An ordered list of memory accesses that occurred. These should be assumed
+    /// to be overcautious; that is, if the size of an access is uncertain it is
+    /// pessimistically rounded up, and if the type (read/write/both) is uncertain
+    /// it is reported as whatever would be safest to assume; i.e. a read + maybe-write
+    /// becomes a read + write, etc.
+    pub acc_events: Vec<AccessEvent>,
+}
+
+/// A single memory access, conservatively overestimated
+/// in case of ambiguity.
+#[derive(serde::Serialize, serde::Deserialize, Debug)]
+pub enum AccessEvent {
+    /// A read may have occurred on no more than the specified address range.
+    Read(Range<usize>),
+    /// A write may have occurred on no more than the specified address range.
+    Write(Range<usize>),
+}
diff --git a/src/tools/miri/src/shims/native_lib/trace/mod.rs b/src/tools/miri/src/shims/native_lib/trace/mod.rs
new file mode 100644
index 00000000000..174b06b3ac5
--- /dev/null
+++ b/src/tools/miri/src/shims/native_lib/trace/mod.rs
@@ -0,0 +1,8 @@
+mod child;
+pub mod messages;
+mod parent;
+
+pub use self::child::{Supervisor, init_sv, register_retcode_sv};
+
+/// The size of the temporary stack we use for callbacks that the server executes in the client.
+const CALLBACK_STACK_SIZE: usize = 1024;
diff --git a/src/tools/miri/src/shims/native_lib/trace/parent.rs b/src/tools/miri/src/shims/native_lib/trace/parent.rs
new file mode 100644
index 00000000000..dfb0b35da69
--- /dev/null
+++ b/src/tools/miri/src/shims/native_lib/trace/parent.rs
@@ -0,0 +1,660 @@
+use std::sync::atomic::{AtomicPtr, AtomicUsize};
+
+use ipc_channel::ipc;
+use nix::sys::{ptrace, signal, wait};
+use nix::unistd;
+
+use super::CALLBACK_STACK_SIZE;
+use super::messages::{AccessEvent, Confirmation, MemEvents, StartFfiInfo, TraceRequest};
+
+/// The flags to use when calling `waitid()`.
+/// Since bitwise or on the nix version of these flags is implemented as a trait,
+/// this cannot be const directly so we do it this way.
+const WAIT_FLAGS: wait::WaitPidFlag =
+    wait::WaitPidFlag::from_bits_truncate(libc::WUNTRACED | libc::WEXITED);
+
+/// Arch-specific maximum size a single access might perform. x86 value is set
+/// assuming nothing bigger than AVX-512 is available.
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+const ARCH_MAX_ACCESS_SIZE: usize = 64;
+/// The largest arm64 simd instruction operates on 16 bytes.
+#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
+const ARCH_MAX_ACCESS_SIZE: usize = 16;
+
+/// The default word size on a given platform, in bytes.
+#[cfg(any(target_arch = "x86", target_arch = "arm"))]
+const ARCH_WORD_SIZE: usize = 4;
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+const ARCH_WORD_SIZE: usize = 8;
+
+/// The address of the page set to be edited, initialised to a sentinel null
+/// pointer.
+static PAGE_ADDR: AtomicPtr<u8> = AtomicPtr::new(std::ptr::null_mut());
+/// The host pagesize, initialised to a sentinel zero value.
+pub static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
+/// How many consecutive pages to unprotect. 1 by default, unlikely to be set
+/// higher than 2.
+static PAGE_COUNT: AtomicUsize = AtomicUsize::new(1);
+
+/// Allows us to get common arguments from the `user_regs_t` across architectures.
+/// Normally this would land us ABI hell, but thankfully all of our usecases
+/// consist of functions with a small number of register-sized integer arguments.
+/// See <https://man7.org/linux/man-pages/man2/syscall.2.html> for sources.
+trait ArchIndependentRegs {
+    /// Gets the address of the instruction pointer.
+    fn ip(&self) -> usize;
+    /// Set the instruction pointer; remember to also set the stack pointer, or
+    /// else the stack might get messed up!
+    fn set_ip(&mut self, ip: usize);
+    /// Set the stack pointer, ideally to a zeroed-out area.
+    fn set_sp(&mut self, sp: usize);
+}
+
+// It's fine / desirable behaviour for values to wrap here, we care about just
+// preserving the bit pattern.
+#[cfg(target_arch = "x86_64")]
+#[expect(clippy::as_conversions)]
+#[rustfmt::skip]
+impl ArchIndependentRegs for libc::user_regs_struct {
+    #[inline]
+    fn ip(&self) -> usize { self.rip as _ }
+    #[inline]
+    fn set_ip(&mut self, ip: usize) { self.rip = ip as _ }
+    #[inline]
+    fn set_sp(&mut self, sp: usize) { self.rsp = sp as _ }
+}
+
+#[cfg(target_arch = "x86")]
+#[expect(clippy::as_conversions)]
+#[rustfmt::skip]
+impl ArchIndependentRegs for libc::user_regs_struct {
+    #[inline]
+    fn ip(&self) -> usize { self.eip as _ }
+    #[inline]
+    fn set_ip(&mut self, ip: usize) { self.eip = ip as _ }
+    #[inline]
+    fn set_sp(&mut self, sp: usize) { self.esp = sp as _ }
+}
+
+#[cfg(target_arch = "aarch64")]
+#[expect(clippy::as_conversions)]
+#[rustfmt::skip]
+impl ArchIndependentRegs for libc::user_regs_struct {
+    #[inline]
+    fn ip(&self) -> usize { self.pc as _ }
+    #[inline]
+    fn set_ip(&mut self, ip: usize) { self.pc = ip as _ }
+    #[inline]
+    fn set_sp(&mut self, sp: usize) { self.sp = sp as _ }
+}
+
+/// A unified event representing something happening on the child process. Wraps
+/// `nix`'s `WaitStatus` and our custom signals so it can all be done with one
+/// `match` statement.
+pub enum ExecEvent {
+    /// Child process requests that we begin monitoring it.
+    Start(StartFfiInfo),
+    /// Child requests that we stop monitoring and pass over the events we
+    /// detected.
+    End,
+    /// The child process with the specified pid was stopped by the given signal.
+    Status(unistd::Pid, signal::Signal),
+    /// The child process with the specified pid entered or existed a syscall.
+    Syscall(unistd::Pid),
+    /// A child process exited or was killed; if we have a return code, it is
+    /// specified.
+    Died(Option<i32>),
+}
+
+/// A listener for the FFI start info channel along with relevant state.
+pub struct ChildListener {
+    /// The matching channel for the child's `Supervisor` struct.
+    pub message_rx: ipc::IpcReceiver<TraceRequest>,
+    /// Whether an FFI call is currently ongoing.
+    pub attached: bool,
+    /// If `Some`, overrides the return code with the given value.
+    pub override_retcode: Option<i32>,
+}
+
+impl Iterator for ChildListener {
+    type Item = ExecEvent;
+
+    // Allows us to monitor the child process by just iterating over the listener.
+    // NB: This should never return None!
+    fn next(&mut self) -> Option<Self::Item> {
+        // Do not block if the child has nothing to report for `waitid`.
+        let opts = WAIT_FLAGS | wait::WaitPidFlag::WNOHANG;
+        loop {
+            // Listen to any child, not just the main one. Important if we want
+            // to allow the C code to fork further, along with being a bit of
+            // defensive programming since Linux sometimes assigns threads of
+            // the same process different PIDs with unpredictable rules...
+            match wait::waitid(wait::Id::All, opts) {
+                Ok(stat) =>
+                    match stat {
+                        // Child exited normally with a specific code set.
+                        wait::WaitStatus::Exited(_, code) => {
+                            let code = self.override_retcode.unwrap_or(code);
+                            return Some(ExecEvent::Died(Some(code)));
+                        }
+                        // Child was killed by a signal, without giving a code.
+                        wait::WaitStatus::Signaled(_, _, _) =>
+                            return Some(ExecEvent::Died(self.override_retcode)),
+                        // Child entered a syscall. Since we're always technically
+                        // tracing, only pass this along if we're actively
+                        // monitoring the child.
+                        wait::WaitStatus::PtraceSyscall(pid) =>
+                            if self.attached {
+                                return Some(ExecEvent::Syscall(pid));
+                            },
+                        // Child with the given pid was stopped by the given signal.
+                        // It's somewhat dubious when this is returned instead of
+                        // WaitStatus::Stopped, but for our purposes they are the
+                        // same thing.
+                        wait::WaitStatus::PtraceEvent(pid, signal, _) =>
+                            if self.attached {
+                                // This is our end-of-FFI signal!
+                                if signal == signal::SIGUSR1 {
+                                    self.attached = false;
+                                    return Some(ExecEvent::End);
+                                } else {
+                                    return Some(ExecEvent::Status(pid, signal));
+                                }
+                            } else {
+                                // Just pass along the signal.
+                                ptrace::cont(pid, signal).unwrap();
+                            },
+                        // Child was stopped at the given signal. Same logic as for
+                        // WaitStatus::PtraceEvent.
+                        wait::WaitStatus::Stopped(pid, signal) =>
+                            if self.attached {
+                                if signal == signal::SIGUSR1 {
+                                    self.attached = false;
+                                    return Some(ExecEvent::End);
+                                } else {
+                                    return Some(ExecEvent::Status(pid, signal));
+                                }
+                            } else {
+                                ptrace::cont(pid, signal).unwrap();
+                            },
+                        _ => (),
+                    },
+                // This case should only trigger if all children died and we
+                // somehow missed that, but it's best we not allow any room
+                // for deadlocks.
+                Err(_) => return Some(ExecEvent::Died(None)),
+            }
+
+            // Similarly, do a non-blocking poll of the IPC channel.
+            if let Ok(req) = self.message_rx.try_recv() {
+                match req {
+                    TraceRequest::StartFfi(info) =>
+                    // Should never trigger - but better to panic explicitly than deadlock!
+                        if self.attached {
+                            panic!("Attempting to begin FFI multiple times!");
+                        } else {
+                            self.attached = true;
+                            return Some(ExecEvent::Start(info));
+                        },
+                    TraceRequest::OverrideRetcode(code) => self.override_retcode = Some(code),
+                }
+            }
+
+            // Not ideal, but doing anything else might sacrifice performance.
+            std::thread::yield_now();
+        }
+    }
+}
+
+/// An error came up while waiting on the child process to do something.
+/// It likely died, with this return code if we have one.
+#[derive(Debug)]
+pub struct ExecEnd(pub Option<i32>);
+
+/// This is the main loop of the supervisor process. It runs in a separate
+/// process from the rest of Miri (but because we fork, addresses for anything
+/// created before the fork - like statics - are the same).
+pub fn sv_loop(
+    listener: ChildListener,
+    init_pid: unistd::Pid,
+    event_tx: ipc::IpcSender<MemEvents>,
+    confirm_tx: ipc::IpcSender<Confirmation>,
+) -> Result<!, ExecEnd> {
+    // Get the pagesize set and make sure it isn't still on the zero sentinel value!
+    let page_size = PAGE_SIZE.load(std::sync::atomic::Ordering::Relaxed);
+    assert_ne!(page_size, 0);
+
+    // Things that we return to the child process.
+    let mut acc_events = Vec::new();
+
+    // Memory allocated for the MiriMachine.
+    let mut ch_pages = Vec::new();
+    let mut ch_stack = None;
+
+    // An instance of the Capstone disassembler, so we don't spawn one on every access.
+    let cs = get_disasm();
+
+    // The pid of the last process we interacted with, used by default if we don't have a
+    // reason to use a different one.
+    let mut curr_pid = init_pid;
+
+    // There's an initial sigstop we need to deal with.
+    wait_for_signal(Some(curr_pid), signal::SIGSTOP, false)?;
+    ptrace::cont(curr_pid, None).unwrap();
+
+    for evt in listener {
+        match evt {
+            // start_ffi was called by the child, so prep memory.
+            ExecEvent::Start(ch_info) => {
+                // All the pages that the child process is "allowed to" access.
+                ch_pages = ch_info.page_ptrs;
+                // And the temporary callback stack it allocated for us to use later.
+                ch_stack = Some(ch_info.stack_ptr);
+
+                // We received the signal and are no longer in the main listener loop,
+                // so we can let the child move on to the end of start_ffi where it will
+                // raise a SIGSTOP. We need it to be signal-stopped *and waited for* in
+                // order to do most ptrace operations!
+                confirm_tx.send(Confirmation).unwrap();
+                // We can't trust simply calling `Pid::this()` in the child process to give the right
+                // PID for us, so we get it this way.
+                curr_pid = wait_for_signal(None, signal::SIGSTOP, false).unwrap();
+
+                ptrace::syscall(curr_pid, None).unwrap();
+            }
+            // end_ffi was called by the child.
+            ExecEvent::End => {
+                // Hand over the access info we traced.
+                event_tx.send(MemEvents { acc_events }).unwrap();
+                // And reset our values.
+                acc_events = Vec::new();
+                ch_stack = None;
+
+                // No need to monitor syscalls anymore, they'd just be ignored.
+                ptrace::cont(curr_pid, None).unwrap();
+            }
+            // Child process was stopped by a signal
+            ExecEvent::Status(pid, signal) =>
+                match signal {
+                    // If it was a segfault, check if it was an artificial one
+                    // caused by it trying to access the MiriMachine memory.
+                    signal::SIGSEGV =>
+                        handle_segfault(
+                            pid,
+                            &ch_pages,
+                            ch_stack.unwrap(),
+                            page_size,
+                            &cs,
+                            &mut acc_events,
+                        )?,
+                    // Something weird happened.
+                    _ => {
+                        eprintln!("Process unexpectedly got {signal}; continuing...");
+                        // In case we're not tracing
+                        if ptrace::syscall(pid, None).is_err() {
+                            // If *this* fails too, something really weird happened
+                            // and it's probably best to just panic.
+                            signal::kill(pid, signal::SIGCONT).unwrap();
+                        }
+                    }
+                },
+            // Child entered a syscall; we wait for exits inside of this, so it
+            // should never trigger on return from a syscall we care about.
+            ExecEvent::Syscall(pid) => {
+                ptrace::syscall(pid, None).unwrap();
+            }
+            ExecEvent::Died(code) => {
+                return Err(ExecEnd(code));
+            }
+        }
+    }
+
+    unreachable!()
+}
+
+/// Spawns a Capstone disassembler for the host architecture.
+#[rustfmt::skip]
+fn get_disasm() -> capstone::Capstone {
+    use capstone::prelude::*;
+    let cs_pre = Capstone::new();
+    {
+        #[cfg(target_arch = "x86_64")]
+        {cs_pre.x86().mode(arch::x86::ArchMode::Mode64)}
+        #[cfg(target_arch = "x86")]
+        {cs_pre.x86().mode(arch::x86::ArchMode::Mode32)}
+        #[cfg(target_arch = "aarch64")]
+        {cs_pre.arm64().mode(arch::arm64::ArchMode::Arm)}
+        #[cfg(target_arch = "arm")]
+        {cs_pre.arm().mode(arch::arm::ArchMode::Arm)}
+    }
+    .detail(true)
+    .build()
+    .unwrap()
+}
+
+/// Waits for `wait_signal`. If `init_cont`, it will first do a `ptrace::cont`.
+/// We want to avoid that in some cases, like at the beginning of FFI.
+///
+/// If `pid` is `None`, only one wait will be done and `init_cont` should be false.
+fn wait_for_signal(
+    pid: Option<unistd::Pid>,
+    wait_signal: signal::Signal,
+    init_cont: bool,
+) -> Result<unistd::Pid, ExecEnd> {
+    if init_cont {
+        ptrace::cont(pid.unwrap(), None).unwrap();
+    }
+    // Repeatedly call `waitid` until we get the signal we want, or the process dies.
+    loop {
+        let wait_id = match pid {
+            Some(pid) => wait::Id::Pid(pid),
+            None => wait::Id::All,
+        };
+        let stat = wait::waitid(wait_id, WAIT_FLAGS).map_err(|_| ExecEnd(None))?;
+        let (signal, pid) = match stat {
+            // Report the cause of death, if we know it.
+            wait::WaitStatus::Exited(_, code) => {
+                return Err(ExecEnd(Some(code)));
+            }
+            wait::WaitStatus::Signaled(_, _, _) => return Err(ExecEnd(None)),
+            wait::WaitStatus::Stopped(pid, signal) => (signal, pid),
+            wait::WaitStatus::PtraceEvent(pid, signal, _) => (signal, pid),
+            // This covers PtraceSyscall and variants that are impossible with
+            // the flags set (e.g. WaitStatus::StillAlive).
+            _ => {
+                ptrace::cont(pid.unwrap(), None).unwrap();
+                continue;
+            }
+        };
+        if signal == wait_signal {
+            return Ok(pid);
+        } else {
+            ptrace::cont(pid, signal).map_err(|_| ExecEnd(None))?;
+        }
+    }
+}
+
+/// Grabs the access that caused a segfault and logs it down if it's to our memory,
+/// or kills the child and returns the appropriate error otherwise.
+fn handle_segfault(
+    pid: unistd::Pid,
+    ch_pages: &[usize],
+    ch_stack: usize,
+    page_size: usize,
+    cs: &capstone::Capstone,
+    acc_events: &mut Vec<AccessEvent>,
+) -> Result<(), ExecEnd> {
+    /// This is just here to not pollute the main namespace with `capstone::prelude::*`.
+    #[inline]
+    fn capstone_disassemble(
+        instr: &[u8],
+        addr: usize,
+        cs: &capstone::Capstone,
+        acc_events: &mut Vec<AccessEvent>,
+    ) -> capstone::CsResult<()> {
+        use capstone::prelude::*;
+
+        // The arch_detail is what we care about, but it relies on these temporaries
+        // that we can't drop. 0x1000 is the default base address for Captsone, and
+        // we're expecting 1 instruction.
+        let insns = cs.disasm_count(instr, 0x1000, 1)?;
+        let ins_detail = cs.insn_detail(&insns[0])?;
+        let arch_detail = ins_detail.arch_detail();
+
+        for op in arch_detail.operands() {
+            match op {
+                #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+                arch::ArchOperand::X86Operand(x86_operand) => {
+                    match x86_operand.op_type {
+                        // We only care about memory accesses
+                        arch::x86::X86OperandType::Mem(_) => {
+                            let push = addr..addr.strict_add(usize::from(x86_operand.size));
+                            // It's called a "RegAccessType" but it also applies to memory
+                            let acc_ty = x86_operand.access.unwrap();
+                            if acc_ty.is_readable() {
+                                acc_events.push(AccessEvent::Read(push.clone()));
+                            }
+                            if acc_ty.is_writable() {
+                                acc_events.push(AccessEvent::Write(push));
+                            }
+                        }
+                        _ => (),
+                    }
+                }
+                #[cfg(target_arch = "aarch64")]
+                arch::ArchOperand::Arm64Operand(arm64_operand) => {
+                    // Annoyingly, we don't always get the size here, so just be pessimistic for now.
+                    match arm64_operand.op_type {
+                        arch::arm64::Arm64OperandType::Mem(_) => {
+                            // B = 1 byte, H = 2 bytes, S = 4 bytes, D = 8 bytes, Q = 16 bytes.
+                            let size = match arm64_operand.vas {
+                                // Not an fp/simd instruction.
+                                arch::arm64::Arm64Vas::ARM64_VAS_INVALID => ARCH_WORD_SIZE,
+                                // 1 byte.
+                                arch::arm64::Arm64Vas::ARM64_VAS_1B => 1,
+                                // 2 bytes.
+                                arch::arm64::Arm64Vas::ARM64_VAS_1H => 2,
+                                // 4 bytes.
+                                arch::arm64::Arm64Vas::ARM64_VAS_4B
+                                | arch::arm64::Arm64Vas::ARM64_VAS_2H
+                                | arch::arm64::Arm64Vas::ARM64_VAS_1S => 4,
+                                // 8 bytes.
+                                arch::arm64::Arm64Vas::ARM64_VAS_8B
+                                | arch::arm64::Arm64Vas::ARM64_VAS_4H
+                                | arch::arm64::Arm64Vas::ARM64_VAS_2S
+                                | arch::arm64::Arm64Vas::ARM64_VAS_1D => 8,
+                                // 16 bytes.
+                                arch::arm64::Arm64Vas::ARM64_VAS_16B
+                                | arch::arm64::Arm64Vas::ARM64_VAS_8H
+                                | arch::arm64::Arm64Vas::ARM64_VAS_4S
+                                | arch::arm64::Arm64Vas::ARM64_VAS_2D
+                                | arch::arm64::Arm64Vas::ARM64_VAS_1Q => 16,
+                            };
+                            let push = addr..addr.strict_add(size);
+                            // FIXME: This now has access type info in the latest
+                            // git version of capstone because this pissed me off
+                            // and I added it. Change this when it updates.
+                            acc_events.push(AccessEvent::Read(push.clone()));
+                            acc_events.push(AccessEvent::Write(push));
+                        }
+                        _ => (),
+                    }
+                }
+                #[cfg(target_arch = "arm")]
+                arch::ArchOperand::ArmOperand(arm_operand) =>
+                    match arm_operand.op_type {
+                        arch::arm::ArmOperandType::Mem(_) => {
+                            // We don't get info on the size of the access, but
+                            // we're at least told if it's a vector instruction.
+                            let size = if arm_operand.vector_index.is_some() {
+                                ARCH_MAX_ACCESS_SIZE
+                            } else {
+                                ARCH_WORD_SIZE
+                            };
+                            let push = addr..addr.strict_add(size);
+                            let acc_ty = arm_operand.access.unwrap();
+                            if acc_ty.is_readable() {
+                                acc_events.push(AccessEvent::Read(push.clone()));
+                            }
+                            if acc_ty.is_writable() {
+                                acc_events.push(AccessEvent::Write(push));
+                            }
+                        }
+                        _ => (),
+                    },
+                _ => unimplemented!(),
+            }
+        }
+
+        Ok(())
+    }
+
+    // Get information on what caused the segfault. This contains the address
+    // that triggered it.
+    let siginfo = ptrace::getsiginfo(pid).unwrap();
+    // All x86, ARM, etc. instructions only have at most one memory operand
+    // (thankfully!)
+    // SAFETY: si_addr is safe to call.
+    let addr = unsafe { siginfo.si_addr().addr() };
+    let page_addr = addr.strict_sub(addr.strict_rem(page_size));
+
+    if !ch_pages.iter().any(|pg| (*pg..pg.strict_add(page_size)).contains(&addr)) {
+        // This was a real segfault (not one of the Miri memory pages), so print some debug info and
+        // quit.
+        let regs = ptrace::getregs(pid).unwrap();
+        eprintln!("Segfault occurred during FFI at {addr:#018x}");
+        eprintln!("Expected access on pages: {ch_pages:#018x?}");
+        eprintln!("Register dump: {regs:#x?}");
+        ptrace::kill(pid).unwrap();
+        return Err(ExecEnd(None));
+    }
+
+    // Overall structure:
+    // - Get the address that caused the segfault
+    // - Unprotect the memory: we force the child to execute `mempr_off`, passing parameters via
+    //   global atomic variables. This is what we use the temporary callback stack for.
+    // - Step 1 instruction
+    // - Parse executed code to estimate size & type of access
+    // - Reprotect the memory by executing `mempr_on` in the child.
+    // - Continue
+
+    // Ensure the stack is properly zeroed out!
+    for a in (ch_stack..ch_stack.strict_add(CALLBACK_STACK_SIZE)).step_by(ARCH_WORD_SIZE) {
+        ptrace::write(pid, std::ptr::with_exposed_provenance_mut(a), 0).unwrap();
+    }
+
+    // Guard against both architectures with upwards and downwards-growing stacks.
+    let stack_ptr = ch_stack.strict_add(CALLBACK_STACK_SIZE / 2);
+    let regs_bak = ptrace::getregs(pid).unwrap();
+    let mut new_regs = regs_bak;
+    let ip_prestep = regs_bak.ip();
+
+    // Move the instr ptr into the deprotection code.
+    #[expect(clippy::as_conversions)]
+    new_regs.set_ip(mempr_off as usize);
+    // Don't mess up the stack by accident!
+    new_regs.set_sp(stack_ptr);
+
+    // Modify the PAGE_ADDR global on the child process to point to the page
+    // that we want unprotected.
+    ptrace::write(
+        pid,
+        (&raw const PAGE_ADDR).cast_mut().cast(),
+        libc::c_long::try_from(page_addr).unwrap(),
+    )
+    .unwrap();
+
+    // Check if we also own the next page, and if so unprotect it in case
+    // the access spans the page boundary.
+    let flag = if ch_pages.contains(&page_addr.strict_add(page_size)) { 2 } else { 1 };
+    ptrace::write(pid, (&raw const PAGE_COUNT).cast_mut().cast(), flag).unwrap();
+
+    ptrace::setregs(pid, new_regs).unwrap();
+
+    // Our mempr_* functions end with a raise(SIGSTOP).
+    wait_for_signal(Some(pid), signal::SIGSTOP, true)?;
+
+    // Step 1 instruction.
+    ptrace::setregs(pid, regs_bak).unwrap();
+    ptrace::step(pid, None).unwrap();
+    // Don't use wait_for_signal here since 1 instruction doesn't give room
+    // for any uncertainty + we don't want it `cont()`ing randomly by accident
+    // Also, don't let it continue with unprotected memory if something errors!
+    let _ = wait::waitid(wait::Id::Pid(pid), WAIT_FLAGS).map_err(|_| ExecEnd(None))?;
+
+    // Zero out again to be safe
+    for a in (ch_stack..ch_stack.strict_add(CALLBACK_STACK_SIZE)).step_by(ARCH_WORD_SIZE) {
+        ptrace::write(pid, std::ptr::with_exposed_provenance_mut(a), 0).unwrap();
+    }
+
+    // Save registers and grab the bytes that were executed. This would
+    // be really nasty if it was a jump or similar but those thankfully
+    // won't do memory accesses and so can't trigger this!
+    let regs_bak = ptrace::getregs(pid).unwrap();
+    new_regs = regs_bak;
+    let ip_poststep = regs_bak.ip();
+    // We need to do reads/writes in word-sized chunks.
+    let diff = (ip_poststep.strict_sub(ip_prestep)).div_ceil(ARCH_WORD_SIZE);
+    let instr = (ip_prestep..ip_prestep.strict_add(diff)).fold(vec![], |mut ret, ip| {
+        // This only needs to be a valid pointer in the child process, not ours.
+        ret.append(
+            &mut ptrace::read(pid, std::ptr::without_provenance_mut(ip))
+                .unwrap()
+                .to_ne_bytes()
+                .to_vec(),
+        );
+        ret
+    });
+
+    // Now figure out the size + type of access and log it down.
+    // This will mark down e.g. the same area being read multiple times,
+    // since it's more efficient to compress the accesses at the end.
+    if capstone_disassemble(&instr, addr, cs, acc_events).is_err() {
+        // Read goes first because we need to be pessimistic.
+        acc_events.push(AccessEvent::Read(addr..addr.strict_add(ARCH_MAX_ACCESS_SIZE)));
+        acc_events.push(AccessEvent::Write(addr..addr.strict_add(ARCH_MAX_ACCESS_SIZE)));
+    }
+
+    // Reprotect everything and continue.
+    #[expect(clippy::as_conversions)]
+    new_regs.set_ip(mempr_on as usize);
+    new_regs.set_sp(stack_ptr);
+    ptrace::setregs(pid, new_regs).unwrap();
+    wait_for_signal(Some(pid), signal::SIGSTOP, true)?;
+
+    ptrace::setregs(pid, regs_bak).unwrap();
+    ptrace::syscall(pid, None).unwrap();
+    Ok(())
+}
+
+// We only get dropped into these functions via offsetting the instr pointer
+// manually, so we *must not ever* unwind from them.
+
+/// Disables protections on the page whose address is currently in `PAGE_ADDR`.
+///
+/// SAFETY: `PAGE_ADDR` should be set to a page-aligned pointer to an owned page,
+/// `PAGE_SIZE` should be the host pagesize, and the range from `PAGE_ADDR` to
+/// `PAGE_SIZE` * `PAGE_COUNT` must be owned and allocated memory. No other threads
+/// should be running.
+pub unsafe extern "C" fn mempr_off() {
+    use std::sync::atomic::Ordering;
+
+    // Again, cannot allow unwinds to happen here.
+    let len = PAGE_SIZE.load(Ordering::Relaxed).saturating_mul(PAGE_COUNT.load(Ordering::Relaxed));
+    // SAFETY: Upheld by "caller".
+    unsafe {
+        // It's up to the caller to make sure this doesn't actually overflow, but
+        // we mustn't unwind from here, so...
+        if libc::mprotect(
+            PAGE_ADDR.load(Ordering::Relaxed).cast(),
+            len,
+            libc::PROT_READ | libc::PROT_WRITE,
+        ) != 0
+        {
+            // Can't return or unwind, but we can do this.
+            std::process::exit(-1);
+        }
+    }
+    // If this fails somehow we're doomed.
+    if signal::raise(signal::SIGSTOP).is_err() {
+        std::process::exit(-1);
+    }
+}
+
+/// Reenables protection on the page set by `PAGE_ADDR`.
+///
+/// SAFETY: See `mempr_off()`.
+pub unsafe extern "C" fn mempr_on() {
+    use std::sync::atomic::Ordering;
+
+    let len = PAGE_SIZE.load(Ordering::Relaxed).wrapping_mul(PAGE_COUNT.load(Ordering::Relaxed));
+    // SAFETY: Upheld by "caller".
+    unsafe {
+        if libc::mprotect(PAGE_ADDR.load(Ordering::Relaxed).cast(), len, libc::PROT_NONE) != 0 {
+            std::process::exit(-1);
+        }
+    }
+    if signal::raise(signal::SIGSTOP).is_err() {
+        std::process::exit(-1);
+    }
+}
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 14ebb22dc2b..b3c58397a02 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -945,8 +945,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pthread_join" => {
                 let [thread, retval] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
-                let res = this.pthread_join(thread, retval)?;
-                this.write_scalar(res, dest)?;
+                this.pthread_join(thread, retval, dest)?;
             }
             "pthread_detach" => {
                 let [thread] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs
index 8e5a3021b1c..47732f811f1 100644
--- a/src/tools/miri/src/shims/unix/linux/mem.rs
+++ b/src/tools/miri/src/shims/unix/linux/mem.rs
@@ -22,8 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let flags = this.read_scalar(flags)?.to_i32()?;
 
         // old_address must be a multiple of the page size
-        #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
-        if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 {
+        if !old_address.addr().bytes().is_multiple_of(this.machine.page_size) || new_size == 0 {
             this.set_last_error(LibcError("EINVAL"))?;
             return interp_ok(this.eval_libc("MAP_FAILED"));
         }
diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs
index aefeee6f7a3..4bbbbc69c08 100644
--- a/src/tools/miri/src/shims/unix/mem.rs
+++ b/src/tools/miri/src/shims/unix/mem.rs
@@ -130,8 +130,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // addr must be a multiple of the page size, but apart from that munmap is just implemented
         // as a dealloc.
-        #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
-        if addr.addr().bytes() % this.machine.page_size != 0 {
+        if !addr.addr().bytes().is_multiple_of(this.machine.page_size) {
             return this.set_last_error_and_return_i32(LibcError("EINVAL"));
         }
 
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index eee2bbcb903..50eb4d92289 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -17,7 +17,7 @@ fn bytewise_equal_atomic_relaxed<'tcx>(
 
     // We do this in chunks of 4, so that we are okay to race with (sufficiently aligned)
     // 4-byte atomic accesses.
-    assert!(size.bytes() % 4 == 0);
+    assert!(size.bytes().is_multiple_of(4));
     for i in 0..(size.bytes() / 4) {
         let offset = Size::from_bytes(i.strict_mul(4));
         let load = |place: &MPlaceTy<'tcx>| {
diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs
index 4b6615b3ea8..a438e71a41d 100644
--- a/src/tools/miri/src/shims/unix/thread.rs
+++ b/src/tools/miri/src/shims/unix/thread.rs
@@ -41,7 +41,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &mut self,
         thread: &OpTy<'tcx>,
         retval: &OpTy<'tcx>,
-    ) -> InterpResult<'tcx, Scalar> {
+        return_dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         if !this.ptr_is_null(this.read_pointer(retval)?)? {
@@ -51,12 +52,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         let thread = this.read_scalar(thread)?.to_int(this.libc_ty_layout("pthread_t").size)?;
         let Ok(thread) = this.thread_id_try_from(thread) else {
-            return interp_ok(this.eval_libc("ESRCH"));
+            this.write_scalar(this.eval_libc("ESRCH"), return_dest)?;
+            return interp_ok(());
         };
 
-        this.join_thread_exclusive(thread)?;
-
-        interp_ok(Scalar::from_u32(0))
+        this.join_thread_exclusive(
+            thread,
+            /* success_retval */ Scalar::from_u32(0),
+            return_dest,
+        )
     }
 
     fn pthread_detach(&mut self, thread: &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 10f6df67ad4..de10357f5fa 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -573,8 +573,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "WaitForSingleObject" => {
                 let [handle, timeout] = this.check_shim(abi, sys_conv, link_name, args)?;
 
-                let ret = this.WaitForSingleObject(handle, timeout)?;
-                this.write_scalar(ret, dest)?;
+                this.WaitForSingleObject(handle, timeout, dest)?;
             }
             "GetCurrentProcess" => {
                 let [] = this.check_shim(abi, sys_conv, link_name, args)?;
diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs
index 56ae88bb1a1..a155ec65a51 100644
--- a/src/tools/miri/src/shims/windows/thread.rs
+++ b/src/tools/miri/src/shims/windows/thread.rs
@@ -58,13 +58,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &mut self,
         handle_op: &OpTy<'tcx>,
         timeout_op: &OpTy<'tcx>,
-    ) -> InterpResult<'tcx, Scalar> {
+        return_dest: &MPlaceTy<'tcx>,
+    ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         let handle = this.read_handle(handle_op, "WaitForSingleObject")?;
         let timeout = this.read_scalar(timeout_op)?.to_u32()?;
 
-        let thread = match handle {
+        let joined_thread_id = match handle {
             Handle::Thread(thread) => thread,
             // Unlike on posix, the outcome of joining the current thread is not documented.
             // On current Windows, it just deadlocks.
@@ -76,8 +77,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             throw_unsup_format!("`WaitForSingleObject` with non-infinite timeout");
         }
 
-        this.join_thread(thread)?;
+        this.join_thread(
+            joined_thread_id,
+            /* success_retval */ this.eval_windows("c", "WAIT_OBJECT_0"),
+            return_dest,
+        )?;
 
-        interp_ok(this.eval_windows("c", "WAIT_OBJECT_0"))
+        interp_ok(())
     }
 }
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 383579198bb..f21c6089a7b 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1066,17 +1066,6 @@ pub fn libm() {
     assert_eq!((-1f32).powf(f32::NEG_INFINITY), 1.0);
     assert_eq!((-1f64).powf(f64::NEG_INFINITY), 1.0);
 
-    // For pow (powf in rust) the C standard says:
-    // x^0 = 1 for all x even a sNaN
-    // FIXME(#4286): this does not match the behavior of all implementations.
-    assert_eq!(SNAN_F32.powf(0.0), 1.0);
-    assert_eq!(SNAN_F64.powf(0.0), 1.0);
-
-    // For pown (powi in rust) the C standard says:
-    // x^0 = 1 for all x even a sNaN
-    // FIXME(#4286): this does not match the behavior of all implementations.
-    assert_eq!(SNAN_F32.powi(0), 1.0);
-    assert_eq!(SNAN_F64.powi(0), 1.0);
 
     assert_eq!(0f32.powi(10), 0.0);
     assert_eq!(0f64.powi(100), 0.0);
@@ -1500,4 +1489,18 @@ fn test_non_determinism() {
     test_operations_f32(12., 5.);
     test_operations_f64(19., 11.);
     test_operations_f128(25., 18.);
+
+
+    // SNaN^0 = (1 | NaN)
+    ensure_nondet(|| f32::powf(SNAN_F32, 0.0).is_nan());
+    ensure_nondet(|| f64::powf(SNAN_F64, 0.0).is_nan());
+
+    // 1^SNaN = (1 | NaN)
+    ensure_nondet(|| f32::powf(1.0, SNAN_F32).is_nan());
+    ensure_nondet(|| f64::powf(1.0, SNAN_F64).is_nan());
+
+    // same as powf (keep it consistent):
+    // x^SNaN = (1 | NaN)
+    ensure_nondet(|| f32::powi(SNAN_F32, 0).is_nan());
+    ensure_nondet(|| f64::powi(SNAN_F64, 0).is_nan());
 }
diff --git a/src/tools/miri/tests/pass/float_nan.rs b/src/tools/miri/tests/pass/float_nan.rs
index cadbbd58af5..3ffdb6868ac 100644
--- a/src/tools/miri/tests/pass/float_nan.rs
+++ b/src/tools/miri/tests/pass/float_nan.rs
@@ -260,6 +260,7 @@ fn test_f32() {
 
     // Intrinsics
     let nan = F32::nan(Neg, Quiet, 0).as_f32();
+    let snan = F32::nan(Neg, Signaling, 1).as_f32();
     check_all_outcomes(
         HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
         || F32::from(f32::min(nan, nan)),
@@ -313,6 +314,18 @@ fn test_f32() {
         HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
         || F32::from(nan.ln_gamma().0),
     );
+    check_all_outcomes(
+        HashSet::from_iter([
+            F32::from(1.0),
+            F32::nan(Pos, Quiet, 0),
+            F32::nan(Neg, Quiet, 0),
+            F32::nan(Pos, Quiet, 1),
+            F32::nan(Neg, Quiet, 1),
+            F32::nan(Pos, Signaling, 1),
+            F32::nan(Neg, Signaling, 1),
+        ]),
+        || F32::from(snan.powf(0.0)),
+    );
 }
 
 fn test_f64() {
@@ -376,6 +389,7 @@ fn test_f64() {
 
     // Intrinsics
     let nan = F64::nan(Neg, Quiet, 0).as_f64();
+    let snan = F64::nan(Neg, Signaling, 1).as_f64();
     check_all_outcomes(
         HashSet::from_iter([F64::nan(Pos, Quiet, 0), F64::nan(Neg, Quiet, 0)]),
         || F64::from(f64::min(nan, nan)),
@@ -433,6 +447,18 @@ fn test_f64() {
         HashSet::from_iter([F64::nan(Pos, Quiet, 0), F64::nan(Neg, Quiet, 0)]),
         || F64::from(nan.ln_gamma().0),
     );
+    check_all_outcomes(
+        HashSet::from_iter([
+            F64::from(1.0),
+            F64::nan(Pos, Quiet, 0),
+            F64::nan(Neg, Quiet, 0),
+            F64::nan(Pos, Quiet, 1),
+            F64::nan(Neg, Quiet, 1),
+            F64::nan(Pos, Signaling, 1),
+            F64::nan(Neg, Signaling, 1),
+        ]),
+        || F64::from(snan.powf(0.0)),
+    );
 }
 
 fn test_casts() {
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index e14ce51f35a..726d4c01cc3 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -570,6 +570,10 @@ fn simd_round() {
         f32x4::from_array([1.0, 1.0, 2.0, -5.0])
     );
     assert_eq!(
+        unsafe { intrinsics::simd_round_ties_even(f32x4::from_array([0.9, 1.001, 2.0, -4.5])) },
+        f32x4::from_array([1.0, 1.0, 2.0, -4.0])
+    );
+    assert_eq!(
         f32x4::from_array([0.9, 1.001, 2.0, -4.5]).trunc(),
         f32x4::from_array([0.0, 1.0, 2.0, -4.0])
     );
@@ -587,6 +591,10 @@ fn simd_round() {
         f64x4::from_array([1.0, 1.0, 2.0, -5.0])
     );
     assert_eq!(
+        unsafe { intrinsics::simd_round_ties_even(f64x4::from_array([0.9, 1.001, 2.0, -4.5])) },
+        f64x4::from_array([1.0, 1.0, 2.0, -4.0])
+    );
+    assert_eq!(
         f64x4::from_array([0.9, 1.001, 2.0, -4.5]).trunc(),
         f64x4::from_array([0.0, 1.0, 2.0, -4.0])
     );
diff --git a/src/tools/rust-installer/README.md b/src/tools/rust-installer/README.md
index 99d8e5ca4cf..505ffe4093f 100644
--- a/src/tools/rust-installer/README.md
+++ b/src/tools/rust-installer/README.md
@@ -51,7 +51,7 @@ To combine installers.
 
 * Make install.sh not have to be customized, pull it's data from a
   config file.
-* Be more resiliant to installation failures, particularly if the disk
+* Be more resilient to installation failures, particularly if the disk
   is full.
 * Pre-install and post-uninstall scripts.
 * Allow components to depend on or contradict other components.
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 7e27e0258c2..4f9af6d53dd 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -1368,7 +1368,6 @@ ui/infinite/issue-41731-infinite-macro-println.rs
 ui/intrinsics/issue-28575.rs
 ui/intrinsics/issue-84297-reifying-copy.rs
 ui/invalid/issue-114435-layout-type-err.rs
-ui/issue-11881.rs
 ui/issue-15924.rs
 ui/issue-16822.rs
 ui/issues-71798.rs
diff --git a/tests/crashes/132882.rs b/tests/crashes/132882.rs
deleted file mode 100644
index 6b5e4dba803..00000000000
--- a/tests/crashes/132882.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #132882
-
-use std::ops::Add;
-
-pub trait Numoid
-where
-    for<N: Numoid> &'a Self: Add<Self>,
-{
-}
-
-pub fn compute<N: Numoid>(a: N) -> N {
-    &a + a
-}
diff --git a/tests/ui/empty-allocation-non-null.rs b/tests/ui/allocator/empty-alloc-nonnull-guarantee.rs
index 45035a42a5f..f4081306c77 100644
--- a/tests/ui/empty-allocation-non-null.rs
+++ b/tests/ui/allocator/empty-alloc-nonnull-guarantee.rs
@@ -1,3 +1,7 @@
+//! Check that the default global Rust allocator produces non-null Box allocations for ZSTs.
+//!
+//! See https://github.com/rust-lang/rust/issues/11998
+
 //@ run-pass
 
 pub fn main() {
diff --git a/tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs
new file mode 100644
index 00000000000..2c4af7da921
--- /dev/null
+++ b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.rs
@@ -0,0 +1,21 @@
+//! Regression test for issue #22077
+//! lifetime parameters must be constrained in associated type definitions
+
+trait Fun {
+    type Output;
+    fn call<'x>(&'x self) -> Self::Output;
+}
+
+struct Holder {
+    x: String,
+}
+
+impl<'a> Fun for Holder {
+    //~^ ERROR E0207
+    type Output = &'a str;
+    fn call<'b>(&'b self) -> &'b str {
+        &self.x[..]
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-unused-rps-in-assoc-type.stderr b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr
index ef61fa4be48..15d0820c895 100644
--- a/tests/ui/impl-unused-rps-in-assoc-type.stderr
+++ b/tests/ui/associated-types/unconstrained-lifetime-assoc-type.stderr
@@ -1,5 +1,5 @@
 error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-rps-in-assoc-type.rs:11:6
+  --> $DIR/unconstrained-lifetime-assoc-type.rs:13:6
    |
 LL | impl<'a> Fun for Holder {
    |      ^^ unconstrained lifetime parameter
diff --git a/tests/ui/inline-disallow-on-variant.rs b/tests/ui/attributes/inline-attribute-enum-variant-error.rs
index d92a4e8cc8d..305b285d2a4 100644
--- a/tests/ui/inline-disallow-on-variant.rs
+++ b/tests/ui/attributes/inline-attribute-enum-variant-error.rs
@@ -1,3 +1,5 @@
+//! Test that #[inline] attribute cannot be applied to enum variants
+
 enum Foo {
     #[inline]
     //~^ ERROR attribute should be applied
diff --git a/tests/ui/inline-disallow-on-variant.stderr b/tests/ui/attributes/inline-attribute-enum-variant-error.stderr
index 255f6bc6a19..a4564d8f722 100644
--- a/tests/ui/inline-disallow-on-variant.stderr
+++ b/tests/ui/attributes/inline-attribute-enum-variant-error.stderr
@@ -1,5 +1,5 @@
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/inline-disallow-on-variant.rs:2:5
+  --> $DIR/inline-attribute-enum-variant-error.rs:4:5
    |
 LL |     #[inline]
    |     ^^^^^^^^^
diff --git a/tests/ui/attributes/inline-main.rs b/tests/ui/attributes/inline-main.rs
new file mode 100644
index 00000000000..7181ee19b67
--- /dev/null
+++ b/tests/ui/attributes/inline-main.rs
@@ -0,0 +1,6 @@
+//! Test that #[inline(always)] can be applied to main function
+
+//@ run-pass
+
+#[inline(always)]
+fn main() {}
diff --git a/tests/ui/attributes/inner-attrs-impl-cfg.rs b/tests/ui/attributes/inner-attrs-impl-cfg.rs
new file mode 100644
index 00000000000..e7a5cfa9e2f
--- /dev/null
+++ b/tests/ui/attributes/inner-attrs-impl-cfg.rs
@@ -0,0 +1,36 @@
+//! Test inner attributes (#![...]) behavior in impl blocks with cfg conditions.
+//!
+//! This test verifies that:
+//! - Inner attributes can conditionally exclude entire impl blocks
+//! - Regular attributes within impl blocks work independently
+//! - Attribute parsing doesn't consume too eagerly
+
+//@ run-pass
+
+struct Foo;
+
+impl Foo {
+    #![cfg(false)]
+
+    fn method(&self) -> bool {
+        false
+    }
+}
+
+impl Foo {
+    #![cfg(not(FALSE))]
+
+    // Check that we don't eat attributes too eagerly.
+    #[cfg(false)]
+    fn method(&self) -> bool {
+        false
+    }
+
+    fn method(&self) -> bool {
+        true
+    }
+}
+
+pub fn main() {
+    assert!(Foo.method());
+}
diff --git a/tests/ui/codegen/maximal-hir-to-mir-coverage-flag.rs b/tests/ui/codegen/maximal-hir-to-mir-coverage-flag.rs
new file mode 100644
index 00000000000..64c31beba28
--- /dev/null
+++ b/tests/ui/codegen/maximal-hir-to-mir-coverage-flag.rs
@@ -0,0 +1,12 @@
+//! Test that -Z maximal-hir-to-mir-coverage flag is accepted.
+//!
+//! Original PR: https://github.com/rust-lang/rust/pull/105286
+
+//@ compile-flags: -Zmaximal-hir-to-mir-coverage
+//@ run-pass
+
+fn main() {
+    let x = 1;
+    let y = x + 1;
+    println!("{y}");
+}
diff --git a/tests/ui/compiletest-self-test/ui-test-missing-annotations-detection.rs b/tests/ui/compiletest-self-test/ui-test-missing-annotations-detection.rs
new file mode 100644
index 00000000000..3a110bdad35
--- /dev/null
+++ b/tests/ui/compiletest-self-test/ui-test-missing-annotations-detection.rs
@@ -0,0 +1,9 @@
+//! Regression test checks UI tests without error annotations are detected as failing.
+//!
+//! This tests that when we forget to use any `//~ ERROR` comments whatsoever,
+//! the test doesn't succeed
+//! Originally created in https://github.com/rust-lang/rust/pull/56244
+
+//@ should-fail
+
+fn main() {}
diff --git a/tests/ui/derives/derive-Debug-enum-variants.rs b/tests/ui/derives/derive-Debug-enum-variants.rs
new file mode 100644
index 00000000000..26f527f7664
--- /dev/null
+++ b/tests/ui/derives/derive-Debug-enum-variants.rs
@@ -0,0 +1,30 @@
+//! Test that `#[derive(Debug)]` for enums correctly formats variant names.
+
+//@ run-pass
+
+#[derive(Debug)]
+enum Foo {
+    A(usize),
+    C,
+}
+
+#[derive(Debug)]
+enum Bar {
+    D,
+}
+
+pub fn main() {
+    // Test variant with data
+    let foo_a = Foo::A(22);
+    assert_eq!("A(22)".to_string(), format!("{:?}", foo_a));
+
+    if let Foo::A(value) = foo_a {
+        println!("Value: {}", value); // This needs to remove #[allow(dead_code)]
+    }
+
+    // Test unit variant
+    assert_eq!("C".to_string(), format!("{:?}", Foo::C));
+
+    // Test unit variant from different enum
+    assert_eq!("D".to_string(), format!("{:?}", Bar::D));
+}
diff --git a/tests/ui/diverging-fn-tail-35849.rs b/tests/ui/diverging-fn-tail-35849.rs
deleted file mode 100644
index f21ce2973e9..00000000000
--- a/tests/ui/diverging-fn-tail-35849.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-fn assert_sizeof() -> ! {
-    unsafe {
-        ::std::mem::transmute::<f64, [u8; 8]>(panic!())
-            //~^ ERROR mismatched types
-    }
-}
-
-fn main() { }
diff --git a/tests/ui/early-ret-binop-add.rs b/tests/ui/early-ret-binop-add.rs
deleted file mode 100644
index 3fec66f35fb..00000000000
--- a/tests/ui/early-ret-binop-add.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-
-#![allow(dead_code)]
-#![allow(unreachable_code)]
-
-use std::ops::Add;
-
-fn wsucc<T:Add<Output=T> + Copy>(n: T) -> T { n + { return n } }
-
-pub fn main() { }
diff --git a/tests/ui/elide-errors-on-mismatched-tuple.rs b/tests/ui/elide-errors-on-mismatched-tuple.rs
deleted file mode 100644
index 7d87b0a7756..00000000000
--- a/tests/ui/elide-errors-on-mismatched-tuple.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Hide irrelevant E0277 errors (#50333)
-
-trait T {}
-
-struct A;
-impl T for A {}
-impl A {
-    fn new() -> Self {
-        Self {}
-    }
-}
-
-fn main() {
-    let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three
-    //~^ ERROR mismatched types
-    let ts: Vec<&dyn T> = vec![&a, &b, &c];
-    // There is no E0277 error above, as `a`, `b` and `c` are `TyErr`
-}
diff --git a/tests/ui/elided-test.rs b/tests/ui/elided-test.rs
deleted file mode 100644
index 2bedc25e17b..00000000000
--- a/tests/ui/elided-test.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// Since we're not compiling a test runner this function should be elided
-// and the build will fail because main doesn't exist
-#[test]
-fn main() {
-} //~ ERROR `main` function not found in crate `elided_test`
diff --git a/tests/ui/elided-test.stderr b/tests/ui/elided-test.stderr
deleted file mode 100644
index 7aebe5d8264..00000000000
--- a/tests/ui/elided-test.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0601]: `main` function not found in crate `elided_test`
-  --> $DIR/elided-test.rs:5:2
-   |
-LL | }
-   |  ^ consider adding a `main` function to `$DIR/elided-test.rs`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0601`.
diff --git a/tests/ui/else-if.rs b/tests/ui/else-if.rs
deleted file mode 100644
index 2161b28c58c..00000000000
--- a/tests/ui/else-if.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ run-pass
-
-pub fn main() {
-    if 1 == 2 {
-        assert!((false));
-    } else if 2 == 3 {
-        assert!((false));
-    } else if 3 == 4 { assert!((false)); } else { assert!((true)); }
-    if 1 == 2 { assert!((false)); } else if 2 == 2 { assert!((true)); }
-    if 1 == 2 {
-        assert!((false));
-    } else if 2 == 2 {
-        if 1 == 1 {
-            assert!((true));
-        } else { if 2 == 1 { assert!((false)); } else { assert!((false)); } }
-    }
-    if 1 == 2 {
-        assert!((false));
-    } else { if 1 == 2 { assert!((false)); } else { assert!((true)); } }
-}
diff --git a/tests/ui/expr/early-return-in-binop.rs b/tests/ui/expr/early-return-in-binop.rs
new file mode 100644
index 00000000000..389d25210f7
--- /dev/null
+++ b/tests/ui/expr/early-return-in-binop.rs
@@ -0,0 +1,19 @@
+//! Test early return within binary operation expressions
+
+//@ run-pass
+
+#![allow(dead_code)]
+#![allow(unreachable_code)]
+
+use std::ops::Add;
+
+/// Function that performs addition with an early return in the right operand
+fn add_with_early_return<T: Add<Output = T> + Copy>(n: T) -> T {
+    n + { return n }
+}
+
+pub fn main() {
+    // Test with different numeric types to ensure generic behavior works
+    let _result1 = add_with_early_return(42i32);
+    let _result2 = add_with_early_return(3.14f64);
+}
diff --git a/tests/ui/logging-only-prints-once.rs b/tests/ui/fmt/debug-single-call.rs
index bb8c29694b5..b59a766c71a 100644
--- a/tests/ui/logging-only-prints-once.rs
+++ b/tests/ui/fmt/debug-single-call.rs
@@ -1,9 +1,12 @@
+//! Test that Debug::fmt is called exactly once during formatting.
+//!
+//! This is a regression test for PR https://github.com/rust-lang/rust/pull/10715
+
 //@ run-pass
 //@ needs-threads
 
 use std::cell::Cell;
-use std::fmt;
-use std::thread;
+use std::{fmt, thread};
 
 struct Foo(Cell<isize>);
 
diff --git a/tests/ui/generics/unconstrained-type-params-inherent-impl.rs b/tests/ui/generics/unconstrained-type-params-inherent-impl.rs
new file mode 100644
index 00000000000..c971de0d1f2
--- /dev/null
+++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.rs
@@ -0,0 +1,32 @@
+//! Test for unconstrained type parameters in inherent implementations
+
+struct MyType;
+
+struct MyType1<T>(T);
+
+trait Bar {
+    type Out;
+}
+
+impl<T> MyType {
+    //~^ ERROR the type parameter `T` is not constrained
+    // T is completely unused - this should fail
+}
+
+impl<T> MyType1<T> {
+    // OK: T is used in the self type `MyType1<T>`
+}
+
+impl<T, U> MyType1<T> {
+    //~^ ERROR the type parameter `U` is not constrained
+    // T is used in self type, but U is unconstrained - this should fail
+}
+
+impl<T, U> MyType1<T>
+where
+    T: Bar<Out = U>,
+{
+    // OK: T is used in self type, U is constrained through the where clause
+}
+
+fn main() {}
diff --git a/tests/ui/impl-unused-tps-inherent.stderr b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr
index 43f63cf968c..19b02ad396c 100644
--- a/tests/ui/impl-unused-tps-inherent.stderr
+++ b/tests/ui/generics/unconstrained-type-params-inherent-impl.stderr
@@ -1,14 +1,14 @@
 error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps-inherent.rs:9:6
+  --> $DIR/unconstrained-type-params-inherent-impl.rs:11:6
    |
 LL | impl<T> MyType {
    |      ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps-inherent.rs:17:8
+  --> $DIR/unconstrained-type-params-inherent-impl.rs:20:9
    |
-LL | impl<T,U> MyType1<T> {
-   |        ^ unconstrained type parameter
+LL | impl<T, U> MyType1<T> {
+   |         ^ unconstrained type parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/impl-unused-rps-in-assoc-type.rs b/tests/ui/impl-unused-rps-in-assoc-type.rs
deleted file mode 100644
index ea41997a698..00000000000
--- a/tests/ui/impl-unused-rps-in-assoc-type.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Test that lifetime parameters must be constrained if they appear in
-// an associated type def'n. Issue #22077.
-
-trait Fun {
-    type Output;
-    fn call<'x>(&'x self) -> Self::Output;
-}
-
-struct Holder { x: String }
-
-impl<'a> Fun for Holder { //~ ERROR E0207
-    type Output = &'a str;
-    fn call<'b>(&'b self) -> &'b str {
-        &self.x[..]
-    }
-}
-
-fn main() { }
diff --git a/tests/ui/impl-unused-tps-inherent.rs b/tests/ui/impl-unused-tps-inherent.rs
deleted file mode 100644
index 83a228e551a..00000000000
--- a/tests/ui/impl-unused-tps-inherent.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-struct MyType;
-
-struct MyType1<T>(T);
-
-trait Bar {
-    type Out;
-}
-
-impl<T> MyType {
-    //~^ ERROR  the type parameter `T` is not constrained
-}
-
-impl<T> MyType1<T> {
-    // OK, T is used in `Foo<T>`.
-}
-
-impl<T,U> MyType1<T> {
-    //~^ ERROR  the type parameter `U` is not constrained
-}
-
-impl<T,U> MyType1<T> where T: Bar<Out=U> {
-    // OK, T is used in `Foo<T>`.
-}
-
-fn main() { }
diff --git a/tests/ui/implicit-method-bind.rs b/tests/ui/implicit-method-bind.rs
deleted file mode 100644
index 5e27516a89a..00000000000
--- a/tests/ui/implicit-method-bind.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
-    let _f = 10i32.abs; //~ ERROR attempted to take value of method
-}
diff --git a/tests/ui/implicit-method-bind.stderr b/tests/ui/implicit-method-bind.stderr
deleted file mode 100644
index e9357113f36..00000000000
--- a/tests/ui/implicit-method-bind.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0615]: attempted to take value of method `abs` on type `i32`
-  --> $DIR/implicit-method-bind.rs:2:20
-   |
-LL |     let _f = 10i32.abs;
-   |                    ^^^ method, not a field
-   |
-help: use parentheses to call the method
-   |
-LL |     let _f = 10i32.abs();
-   |                       ++
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0615`.
diff --git a/tests/ui/double-type-import.rs b/tests/ui/imports/duplicate-use-bindings.rs
index 6b1eb65d5ae..8cec23ea732 100644
--- a/tests/ui/double-type-import.rs
+++ b/tests/ui/imports/duplicate-use-bindings.rs
@@ -1,3 +1,5 @@
+//! Test that duplicate use bindings in same namespace produce error
+
 mod foo {
     pub use self::bar::X;
     use self::bar::X;
diff --git a/tests/ui/double-type-import.stderr b/tests/ui/imports/duplicate-use-bindings.stderr
index 8a8fe05ec19..1d4f1fc82db 100644
--- a/tests/ui/double-type-import.stderr
+++ b/tests/ui/imports/duplicate-use-bindings.stderr
@@ -1,5 +1,5 @@
 error[E0252]: the name `X` is defined multiple times
-  --> $DIR/double-type-import.rs:3:9
+  --> $DIR/duplicate-use-bindings.rs:5:9
    |
 LL |     pub use self::bar::X;
    |             ------------ previous import of the type `X` here
diff --git a/tests/ui/integral-indexing.rs b/tests/ui/indexing/indexing-integral-types.rs
index e20553af8a2..a91696a6fd5 100644
--- a/tests/ui/integral-indexing.rs
+++ b/tests/ui/indexing/indexing-integral-types.rs
@@ -1,16 +1,20 @@
+//! Test that only usize can be used for indexing arrays and slices.
+
 pub fn main() {
     let v: Vec<isize> = vec![0, 1, 2, 3, 4, 5];
     let s: String = "abcdef".to_string();
+
+    // Valid indexing with usize
     v[3_usize];
     v[3];
-    v[3u8];  //~ ERROR the type `[isize]` cannot be indexed by `u8`
-    v[3i8];  //~ ERROR the type `[isize]` cannot be indexed by `i8`
+    v[3u8]; //~ ERROR the type `[isize]` cannot be indexed by `u8`
+    v[3i8]; //~ ERROR the type `[isize]` cannot be indexed by `i8`
     v[3u32]; //~ ERROR the type `[isize]` cannot be indexed by `u32`
     v[3i32]; //~ ERROR the type `[isize]` cannot be indexed by `i32`
     s.as_bytes()[3_usize];
     s.as_bytes()[3];
-    s.as_bytes()[3u8];  //~ ERROR the type `[u8]` cannot be indexed by `u8`
-    s.as_bytes()[3i8];  //~ ERROR the type `[u8]` cannot be indexed by `i8`
+    s.as_bytes()[3u8]; //~ ERROR the type `[u8]` cannot be indexed by `u8`
+    s.as_bytes()[3i8]; //~ ERROR the type `[u8]` cannot be indexed by `i8`
     s.as_bytes()[3u32]; //~ ERROR the type `[u8]` cannot be indexed by `u32`
     s.as_bytes()[3i32]; //~ ERROR the type `[u8]` cannot be indexed by `i32`
 }
diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/indexing/indexing-integral-types.stderr
index 26253e078cb..b63991ec2c4 100644
--- a/tests/ui/integral-indexing.stderr
+++ b/tests/ui/indexing/indexing-integral-types.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the type `[isize]` cannot be indexed by `u8`
-  --> $DIR/integral-indexing.rs:6:7
+  --> $DIR/indexing-integral-types.rs:10:7
    |
 LL |     v[3u8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
@@ -11,7 +11,7 @@ LL |     v[3u8];
    = note: required for `Vec<isize>` to implement `Index<u8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i8`
-  --> $DIR/integral-indexing.rs:7:7
+  --> $DIR/indexing-integral-types.rs:11:7
    |
 LL |     v[3i8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
@@ -23,7 +23,7 @@ LL |     v[3i8];
    = note: required for `Vec<isize>` to implement `Index<i8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `u32`
-  --> $DIR/integral-indexing.rs:8:7
+  --> $DIR/indexing-integral-types.rs:12:7
    |
 LL |     v[3u32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
@@ -35,7 +35,7 @@ LL |     v[3u32];
    = note: required for `Vec<isize>` to implement `Index<u32>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i32`
-  --> $DIR/integral-indexing.rs:9:7
+  --> $DIR/indexing-integral-types.rs:13:7
    |
 LL |     v[3i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
@@ -47,7 +47,7 @@ LL |     v[3i32];
    = note: required for `Vec<isize>` to implement `Index<i32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u8`
-  --> $DIR/integral-indexing.rs:12:18
+  --> $DIR/indexing-integral-types.rs:16:18
    |
 LL |     s.as_bytes()[3u8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
@@ -59,7 +59,7 @@ LL |     s.as_bytes()[3u8];
    = note: required for `[u8]` to implement `Index<u8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i8`
-  --> $DIR/integral-indexing.rs:13:18
+  --> $DIR/indexing-integral-types.rs:17:18
    |
 LL |     s.as_bytes()[3i8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
@@ -71,7 +71,7 @@ LL |     s.as_bytes()[3i8];
    = note: required for `[u8]` to implement `Index<i8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u32`
-  --> $DIR/integral-indexing.rs:14:18
+  --> $DIR/indexing-integral-types.rs:18:18
    |
 LL |     s.as_bytes()[3u32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
@@ -83,7 +83,7 @@ LL |     s.as_bytes()[3u32];
    = note: required for `[u8]` to implement `Index<u32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i32`
-  --> $DIR/integral-indexing.rs:15:18
+  --> $DIR/indexing-integral-types.rs:19:18
    |
 LL |     s.as_bytes()[3i32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
diff --git a/tests/ui/inlined-main.rs b/tests/ui/inlined-main.rs
deleted file mode 100644
index 731ac0dddca..00000000000
--- a/tests/ui/inlined-main.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ run-pass
-
-#[inline(always)]
-fn main() {}
diff --git a/tests/ui/inner-attrs-on-impl.rs b/tests/ui/inner-attrs-on-impl.rs
deleted file mode 100644
index 1dce1cdd261..00000000000
--- a/tests/ui/inner-attrs-on-impl.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ run-pass
-
-struct Foo;
-
-impl Foo {
-    #![cfg(false)]
-
-    fn method(&self) -> bool { false }
-}
-
-impl Foo {
-    #![cfg(not(FALSE))]
-
-    // check that we don't eat attributes too eagerly.
-    #[cfg(false)]
-    fn method(&self) -> bool { false }
-
-    fn method(&self) -> bool { true }
-}
-
-
-pub fn main() {
-    assert!(Foo.method());
-}
diff --git a/tests/ui/inner-module.rs b/tests/ui/inner-module.rs
deleted file mode 100644
index 111f2cab857..00000000000
--- a/tests/ui/inner-module.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-pass
-
-mod inner {
-    pub mod inner2 {
-        pub fn hello() { println!("hello, modular world"); }
-    }
-    pub fn hello() { inner2::hello(); }
-}
-
-pub fn main() { inner::hello(); inner::inner2::hello(); }
diff --git a/tests/ui/inner-static-type-parameter.rs b/tests/ui/inner-static-type-parameter.rs
deleted file mode 100644
index a1994e7529c..00000000000
--- a/tests/ui/inner-static-type-parameter.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// see #9186
-
-enum Bar<T> { What } //~ ERROR parameter `T` is never used
-
-fn foo<T>() {
-    static a: Bar<T> = Bar::What;
-//~^ ERROR can't use generic parameters from outer item
-}
-
-fn main() {
-}
diff --git a/tests/ui/link-section.rs b/tests/ui/linkage-attr/link-section-placement.rs
index a8de8c2e1e7..6a143bfedb4 100644
--- a/tests/ui/link-section.rs
+++ b/tests/ui/linkage-attr/link-section-placement.rs
@@ -1,8 +1,9 @@
+//! Test placement of functions and statics in custom link sections
+
 //@ run-pass
 
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
-
 #![allow(non_upper_case_globals)]
 #[cfg(not(target_vendor = "apple"))]
 #[link_section = ".moretext"]
diff --git a/tests/ui/missing_debug_impls.rs b/tests/ui/lint/missing-debug-implementations-lint.rs
index 3abc0706887..8a93f052f9c 100644
--- a/tests/ui/missing_debug_impls.rs
+++ b/tests/ui/lint/missing-debug-implementations-lint.rs
@@ -1,3 +1,7 @@
+//! Test the `missing_debug_implementations` lint that warns about public types without Debug.
+//!
+//! See https://github.com/rust-lang/rust/issues/20855
+
 //@ compile-flags: --crate-type lib
 #![deny(missing_debug_implementations)]
 #![allow(unused)]
@@ -10,7 +14,6 @@ pub enum A {} //~ ERROR type does not implement `Debug`
 pub enum B {}
 
 pub enum C {}
-
 impl fmt::Debug for C {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         Ok(())
@@ -23,15 +26,14 @@ pub struct Foo; //~ ERROR type does not implement `Debug`
 pub struct Bar;
 
 pub struct Baz;
-
 impl fmt::Debug for Baz {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         Ok(())
     }
 }
 
+// Private types should not trigger the lint
 struct PrivateStruct;
-
 enum PrivateEnum {}
 
 #[derive(Debug)]
diff --git a/tests/ui/missing_debug_impls.stderr b/tests/ui/lint/missing-debug-implementations-lint.stderr
index 0538f207b44..288ab981034 100644
--- a/tests/ui/missing_debug_impls.stderr
+++ b/tests/ui/lint/missing-debug-implementations-lint.stderr
@@ -1,17 +1,17 @@
 error: type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation
-  --> $DIR/missing_debug_impls.rs:7:1
+  --> $DIR/missing-debug-implementations-lint.rs:11:1
    |
 LL | pub enum A {}
    | ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/missing_debug_impls.rs:2:9
+  --> $DIR/missing-debug-implementations-lint.rs:6:9
    |
 LL | #![deny(missing_debug_implementations)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: type does not implement `Debug`; consider adding `#[derive(Debug)]` or a manual implementation
-  --> $DIR/missing_debug_impls.rs:20:1
+  --> $DIR/missing-debug-implementations-lint.rs:23:1
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/unused/must-use-macros.fixed b/tests/ui/lint/unused/must-use-macros.fixed
new file mode 100644
index 00000000000..609d0c6392b
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-macros.fixed
@@ -0,0 +1,60 @@
+// Makes sure the suggestions of the `unused_must_use` lint are not inside
+//
+// See <https://github.com/rust-lang/rust/issues/143025>
+
+//@ check-pass
+//@ run-rustfix
+
+#![expect(unused_macros)]
+#![warn(unused_must_use)]
+
+fn main() {
+    {
+        macro_rules! cmp {
+            ($a:tt, $b:tt) => {
+                $a == $b
+            };
+        }
+
+        // FIXME(Urgau): For some unknown reason the spans we get are not
+        // recorded to be from any expansions, preventing us from either
+        // suggesting in front of the macro or not at all.
+        // cmp!(1, 1);
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:ident, $b:ident) => {
+                $a == $b
+            }; //~^ WARN unused comparison that must be used
+        }
+
+        let a = 1;
+        let b = 1;
+        let _ = cmp!(a, b);
+        //~^ SUGGESTION let _
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:expr, $b:expr) => {
+                $a == $b
+            }; //~^ WARN unused comparison that must be used
+        }
+
+        let _ = cmp!(1, 1);
+        //~^ SUGGESTION let _
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:tt, $b:tt) => {
+                $a.eq(&$b)
+            };
+        }
+
+        let _ = cmp!(1, 1);
+        //~^ WARN unused return value
+        //~| SUGGESTION let _
+    }
+}
diff --git a/tests/ui/lint/unused/must-use-macros.rs b/tests/ui/lint/unused/must-use-macros.rs
new file mode 100644
index 00000000000..63e246ed374
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-macros.rs
@@ -0,0 +1,60 @@
+// Makes sure the suggestions of the `unused_must_use` lint are not inside
+//
+// See <https://github.com/rust-lang/rust/issues/143025>
+
+//@ check-pass
+//@ run-rustfix
+
+#![expect(unused_macros)]
+#![warn(unused_must_use)]
+
+fn main() {
+    {
+        macro_rules! cmp {
+            ($a:tt, $b:tt) => {
+                $a == $b
+            };
+        }
+
+        // FIXME(Urgau): For some unknown reason the spans we get are not
+        // recorded to be from any expansions, preventing us from either
+        // suggesting in front of the macro or not at all.
+        // cmp!(1, 1);
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:ident, $b:ident) => {
+                $a == $b
+            }; //~^ WARN unused comparison that must be used
+        }
+
+        let a = 1;
+        let b = 1;
+        cmp!(a, b);
+        //~^ SUGGESTION let _
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:expr, $b:expr) => {
+                $a == $b
+            }; //~^ WARN unused comparison that must be used
+        }
+
+        cmp!(1, 1);
+        //~^ SUGGESTION let _
+    }
+
+    {
+        macro_rules! cmp {
+            ($a:tt, $b:tt) => {
+                $a.eq(&$b)
+            };
+        }
+
+        cmp!(1, 1);
+        //~^ WARN unused return value
+        //~| SUGGESTION let _
+    }
+}
diff --git a/tests/ui/lint/unused/must-use-macros.stderr b/tests/ui/lint/unused/must-use-macros.stderr
new file mode 100644
index 00000000000..2ad174e10b5
--- /dev/null
+++ b/tests/ui/lint/unused/must-use-macros.stderr
@@ -0,0 +1,48 @@
+warning: unused comparison that must be used
+  --> $DIR/must-use-macros.rs:28:17
+   |
+LL |                 $a == $b
+   |                 ^^^^^^^^ the comparison produces a value
+...
+LL |         cmp!(a, b);
+   |         ---------- in this macro invocation
+   |
+note: the lint level is defined here
+  --> $DIR/must-use-macros.rs:9:9
+   |
+LL | #![warn(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+   = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |         let _ = cmp!(a, b);
+   |         +++++++
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-macros.rs:41:17
+   |
+LL |                 $a == $b
+   |                 ^^^^^^^^ the comparison produces a value
+...
+LL |         cmp!(1, 1);
+   |         ---------- in this macro invocation
+   |
+   = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |         let _ = cmp!(1, 1);
+   |         +++++++
+
+warning: unused return value of `std::cmp::PartialEq::eq` that must be used
+  --> $DIR/must-use-macros.rs:56:9
+   |
+LL |         cmp!(1, 1);
+   |         ^^^^^^^^^^
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |         let _ = cmp!(1, 1);
+   |         +++++++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/log-err-phi.rs b/tests/ui/log-err-phi.rs
deleted file mode 100644
index 1bb97758782..00000000000
--- a/tests/ui/log-err-phi.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ run-pass
-
-pub fn main() {
-    if false {
-        println!("{}", "foobar");
-    }
-}
diff --git a/tests/ui/log-knows-the-names-of-variants.rs b/tests/ui/log-knows-the-names-of-variants.rs
deleted file mode 100644
index cb82cb4878a..00000000000
--- a/tests/ui/log-knows-the-names-of-variants.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ run-pass
-
-#![allow(non_camel_case_types)]
-#![allow(dead_code)]
-#[derive(Debug)]
-enum foo {
-  a(usize),
-  b(String),
-  c,
-}
-
-#[derive(Debug)]
-enum bar {
-  d, e, f
-}
-
-pub fn main() {
-    assert_eq!("a(22)".to_string(), format!("{:?}", foo::a(22)));
-    assert_eq!("c".to_string(), format!("{:?}", foo::c));
-    assert_eq!("d".to_string(), format!("{:?}", bar::d));
-}
diff --git a/tests/ui/loud_ui.rs b/tests/ui/loud_ui.rs
deleted file mode 100644
index 2a73e49e172..00000000000
--- a/tests/ui/loud_ui.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ should-fail
-
-// this test ensures that when we forget to use
-// any `//~ ERROR` comments whatsoever, that the test doesn't succeed
-
-fn main() {}
diff --git a/tests/ui/macros/must-use-in-macro-55516.stderr b/tests/ui/macros/must-use-in-macro-55516.stderr
index 7bf4aaab51c..b93d40d7e5a 100644
--- a/tests/ui/macros/must-use-in-macro-55516.stderr
+++ b/tests/ui/macros/must-use-in-macro-55516.stderr
@@ -7,7 +7,10 @@ LL |     write!(&mut example, "{}", 42);
    = note: this `Result` may be an `Err` variant, which should be handled
    = note: `-W unused-must-use` implied by `-W unused`
    = help: to override `-W unused` add `#[allow(unused_must_use)]`
-   = note: this warning originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = write!(&mut example, "{}", 42);
+   |     +++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/maximal_mir_to_hir_coverage.rs b/tests/ui/maximal_mir_to_hir_coverage.rs
deleted file mode 100644
index e57c83d007e..00000000000
--- a/tests/ui/maximal_mir_to_hir_coverage.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ compile-flags: -Zmaximal-hir-to-mir-coverage
-//@ run-pass
-
-// Just making sure this flag is accepted and doesn't crash the compiler
-
-fn main() {
-  let x = 1;
-  let y = x + 1;
-  println!("{y}");
-}
diff --git a/tests/ui/maybe-bounds.rs b/tests/ui/maybe-bounds.rs
deleted file mode 100644
index 02ed45c656f..00000000000
--- a/tests/ui/maybe-bounds.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-trait Tr: ?Sized {}
-//~^ ERROR `?Trait` is not permitted in supertraits
-
-type A1 = dyn Tr + (?Sized);
-//~^ ERROR `?Trait` is not permitted in trait object types
-type A2 = dyn for<'a> Tr + (?Sized);
-//~^ ERROR `?Trait` is not permitted in trait object types
-
-fn main() {}
diff --git a/tests/ui/method-output-diff-issue-127263.rs b/tests/ui/method-output-diff-issue-127263.rs
deleted file mode 100644
index 85a903e2453..00000000000
--- a/tests/ui/method-output-diff-issue-127263.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-fn bar() {}
-fn foo(x: i32) -> u32 {
-    0
-}
-fn main() {
-    let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308]
-    let f: fn(i32) = foo; //~ ERROR mismatched types [E0308]
-}
diff --git a/tests/ui/methods/method-missing-call.rs b/tests/ui/methods/method-missing-call.rs
deleted file mode 100644
index 7ce1e9a4f1b..00000000000
--- a/tests/ui/methods/method-missing-call.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Tests to make sure that parens are needed for method calls without arguments.
-// outputs text to make sure either an anonymous function is provided or
-// open-close '()' parens are given
-
-
-struct Point {
-    x: isize,
-    y: isize
-}
-impl Point {
-    fn new() -> Point {
-        Point{x:0, y:0}
-    }
-    fn get_x(&self) -> isize {
-        self.x
-    }
-}
-
-fn main() {
-    let point: Point = Point::new();
-    let px: isize =  point
-                        .get_x;//~ ERROR attempted to take value of method `get_x` on type `Point`
-
-    // Ensure the span is useful
-    let ys = &[1,2,3,4,5,6,7];
-    let a = ys.iter()
-              .map(|x| x)
-              .filter(|&&x| x == 1)
-              .filter_map; //~ ERROR attempted to take value of method `filter_map` on type
-}
diff --git a/tests/ui/methods/method-missing-call.stderr b/tests/ui/methods/method-missing-call.stderr
deleted file mode 100644
index bc508461b69..00000000000
--- a/tests/ui/methods/method-missing-call.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error[E0615]: attempted to take value of method `get_x` on type `Point`
-  --> $DIR/method-missing-call.rs:22:26
-   |
-LL |                         .get_x;
-   |                          ^^^^^ method, not a field
-   |
-help: use parentheses to call the method
-   |
-LL |                         .get_x();
-   |                               ++
-
-error[E0615]: attempted to take value of method `filter_map` on type `Filter<Map<std::slice::Iter<'_, {integer}>, {closure@$DIR/method-missing-call.rs:27:20: 27:23}>, {closure@$DIR/method-missing-call.rs:28:23: 28:28}>`
-  --> $DIR/method-missing-call.rs:29:16
-   |
-LL |               .filter_map;
-   |                ^^^^^^^^^^ method, not a field
-   |
-help: use parentheses to call the method
-   |
-LL |               .filter_map(_);
-   |                          +++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0615`.
diff --git a/tests/ui/methods/method-value-without-call.rs b/tests/ui/methods/method-value-without-call.rs
new file mode 100644
index 00000000000..43bee4864b4
--- /dev/null
+++ b/tests/ui/methods/method-value-without-call.rs
@@ -0,0 +1,33 @@
+//! Test taking a method value without parentheses
+
+struct Point {
+    x: isize,
+    y: isize,
+}
+
+impl Point {
+    fn new() -> Point {
+        Point { x: 0, y: 0 }
+    }
+
+    fn get_x(&self) -> isize {
+        self.x
+    }
+}
+
+fn main() {
+    // Test with primitive type method
+    let _f = 10i32.abs; //~ ERROR attempted to take value of method
+
+    // Test with custom type method
+    let point: Point = Point::new();
+    let px: isize = point.get_x; //~ ERROR attempted to take value of method `get_x` on type `Point`
+
+    // Test with method chains - ensure the span is useful
+    let ys = &[1, 2, 3, 4, 5, 6, 7];
+    let a = ys
+        .iter()
+        .map(|x| x)
+        .filter(|&&x| x == 1)
+        .filter_map; //~ ERROR attempted to take value of method `filter_map` on type
+}
diff --git a/tests/ui/methods/method-value-without-call.stderr b/tests/ui/methods/method-value-without-call.stderr
new file mode 100644
index 00000000000..0c3870e2868
--- /dev/null
+++ b/tests/ui/methods/method-value-without-call.stderr
@@ -0,0 +1,36 @@
+error[E0615]: attempted to take value of method `abs` on type `i32`
+  --> $DIR/method-value-without-call.rs:20:20
+   |
+LL |     let _f = 10i32.abs;
+   |                    ^^^ method, not a field
+   |
+help: use parentheses to call the method
+   |
+LL |     let _f = 10i32.abs();
+   |                       ++
+
+error[E0615]: attempted to take value of method `get_x` on type `Point`
+  --> $DIR/method-value-without-call.rs:24:27
+   |
+LL |     let px: isize = point.get_x;
+   |                           ^^^^^ method, not a field
+   |
+help: use parentheses to call the method
+   |
+LL |     let px: isize = point.get_x();
+   |                                ++
+
+error[E0615]: attempted to take value of method `filter_map` on type `Filter<Map<std::slice::Iter<'_, {integer}>, {closure@$DIR/method-value-without-call.rs:30:14: 30:17}>, {closure@$DIR/method-value-without-call.rs:31:17: 31:22}>`
+  --> $DIR/method-value-without-call.rs:32:10
+   |
+LL |         .filter_map;
+   |          ^^^^^^^^^^ method, not a field
+   |
+help: use parentheses to call the method
+   |
+LL |         .filter_map(_);
+   |                    +++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0615`.
diff --git a/tests/ui/mismatched_types/elide-on-tuple-mismatch.rs b/tests/ui/mismatched_types/elide-on-tuple-mismatch.rs
new file mode 100644
index 00000000000..c36d041d296
--- /dev/null
+++ b/tests/ui/mismatched_types/elide-on-tuple-mismatch.rs
@@ -0,0 +1,25 @@
+//! Regression test for issue #50333: elide irrelevant E0277 errors on tuple mismatch
+
+// Hide irrelevant E0277 errors (#50333)
+
+trait T {}
+
+struct A;
+
+impl T for A {}
+
+impl A {
+    fn new() -> Self {
+        Self {}
+    }
+}
+
+fn main() {
+    // This creates a tuple type mismatch: 2-element tuple destructured into 3 variables
+    let (a, b, c) = (A::new(), A::new());
+    //~^ ERROR mismatched types
+
+    // This line should NOT produce an E0277 error about `Sized` trait bounds,
+    // because `a`, `b`, and `c` are `TyErr` due to the mismatch above
+    let _ts: Vec<&dyn T> = vec![&a, &b, &c];
+}
diff --git a/tests/ui/elide-errors-on-mismatched-tuple.stderr b/tests/ui/mismatched_types/elide-on-tuple-mismatch.stderr
index f852a223b42..7de45eb40ca 100644
--- a/tests/ui/elide-errors-on-mismatched-tuple.stderr
+++ b/tests/ui/mismatched_types/elide-on-tuple-mismatch.stderr
@@ -1,7 +1,7 @@
 error[E0308]: mismatched types
-  --> $DIR/elide-errors-on-mismatched-tuple.rs:14:9
+  --> $DIR/elide-on-tuple-mismatch.rs:19:9
    |
-LL |     let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three
+LL |     let (a, b, c) = (A::new(), A::new());
    |         ^^^^^^^^^   -------------------- this expression has type `(A, A)`
    |         |
    |         expected a tuple with 2 elements, found one with 3 elements
diff --git a/tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.rs b/tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.rs
new file mode 100644
index 00000000000..e28ca3e55b5
--- /dev/null
+++ b/tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.rs
@@ -0,0 +1,16 @@
+//! This test checks that when there's a type mismatch between a function item and
+//! a function pointer, the error message focuses on the actual type difference
+//! (return types, argument types) rather than the confusing "pointer vs item" distinction.
+//!
+//! See https://github.com/rust-lang/rust/issues/127263
+
+fn bar() {}
+
+fn foo(x: i32) -> u32 {
+    0
+}
+
+fn main() {
+    let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308]
+    let f: fn(i32) = foo; //~ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/method-output-diff-issue-127263.stderr b/tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.stderr
index 35b86114f16..8d63f2ea2d3 100644
--- a/tests/ui/method-output-diff-issue-127263.stderr
+++ b/tests/ui/mismatched_types/fn-pointer-mismatch-diagnostics.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/method-output-diff-issue-127263.rs:6:26
+  --> $DIR/fn-pointer-mismatch-diagnostics.rs:14:26
    |
 LL |     let b: fn() -> u32 = bar;
    |            -----------   ^^^ expected fn pointer, found fn item
@@ -10,7 +10,7 @@ LL |     let b: fn() -> u32 = bar;
                  found fn item `fn() -> () {bar}`
 
 error[E0308]: mismatched types
-  --> $DIR/method-output-diff-issue-127263.rs:7:22
+  --> $DIR/fn-pointer-mismatch-diagnostics.rs:15:22
    |
 LL |     let f: fn(i32) = foo;
    |            -------   ^^^ expected fn pointer, found fn item
diff --git a/tests/ui/integral-variable-unification-error.rs b/tests/ui/mismatched_types/int-float-type-mismatch.rs
index 8d1621321e8..b45d02730d9 100644
--- a/tests/ui/integral-variable-unification-error.rs
+++ b/tests/ui/mismatched_types/int-float-type-mismatch.rs
@@ -1,3 +1,6 @@
+//! Check that a type mismatch error is reported when trying
+//! to unify a {float} value assignment to an {integer} variable.
+
 fn main() {
     let mut x //~ NOTE expected due to the type of this binding
         =
diff --git a/tests/ui/integral-variable-unification-error.stderr b/tests/ui/mismatched_types/int-float-type-mismatch.stderr
index 1caa6042fd2..43b8609a49d 100644
--- a/tests/ui/integral-variable-unification-error.stderr
+++ b/tests/ui/mismatched_types/int-float-type-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/integral-variable-unification-error.rs:5:9
+  --> $DIR/int-float-type-mismatch.rs:8:9
    |
 LL |     let mut x
    |         ----- expected due to the type of this binding
diff --git a/tests/ui/mod-subitem-as-enum-variant.rs b/tests/ui/mod-subitem-as-enum-variant.rs
deleted file mode 100644
index 959024c46f4..00000000000
--- a/tests/ui/mod-subitem-as-enum-variant.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-mod Mod {
-    pub struct FakeVariant<T>(pub T);
-}
-
-fn main() {
-    Mod::FakeVariant::<i32>(0);
-    Mod::<i32>::FakeVariant(0);
-    //~^ ERROR type arguments are not allowed on module `Mod` [E0109]
-}
diff --git a/tests/ui/modules/nested-modules-basic.rs b/tests/ui/modules/nested-modules-basic.rs
new file mode 100644
index 00000000000..12eccec2808
--- /dev/null
+++ b/tests/ui/modules/nested-modules-basic.rs
@@ -0,0 +1,19 @@
+//! Basic test for nested module functionality and path resolution
+
+//@ run-pass
+
+mod inner {
+    pub mod inner2 {
+        pub fn hello() {
+            println!("hello, modular world");
+        }
+    }
+    pub fn hello() {
+        inner2::hello();
+    }
+}
+
+pub fn main() {
+    inner::hello();
+    inner::inner2::hello();
+}
diff --git a/tests/ui/double-ref.rs b/tests/ui/parser/reference-whitespace-parsing.rs
index eecf68ff209..7109c5911ae 100644
--- a/tests/ui/double-ref.rs
+++ b/tests/ui/parser/reference-whitespace-parsing.rs
@@ -1,3 +1,5 @@
+//! Test parsing of multiple references with various whitespace arrangements
+
 //@ run-pass
 
 #![allow(dead_code)]
diff --git a/tests/ui/max-min-classes.rs b/tests/ui/resolve/struct-function-same-name.rs
index 338a3156a9a..bb2837d7ca6 100644
--- a/tests/ui/max-min-classes.rs
+++ b/tests/ui/resolve/struct-function-same-name.rs
@@ -1,3 +1,5 @@
+//! Test that a struct and function can have the same name
+//!
 //@ run-pass
 
 #![allow(non_snake_case)]
@@ -23,7 +25,7 @@ impl Product for Foo {
 }
 
 fn Foo(x: isize, y: isize) -> Foo {
-    Foo { x: x, y: y }
+    Foo { x, y }
 }
 
 pub fn main() {
diff --git a/tests/ui/lexical-scoping.rs b/tests/ui/resolve/type-param-local-var-shadowing.rs
index f858369f7ce..e08379e2acf 100644
--- a/tests/ui/lexical-scoping.rs
+++ b/tests/ui/resolve/type-param-local-var-shadowing.rs
@@ -1,8 +1,13 @@
+//! Test that items in subscopes correctly shadow type parameters and local variables
+//!
+//! Regression test for https://github.com/rust-lang/rust/issues/23880
+
 //@ run-pass
-// Tests that items in subscopes can shadow type parameters and local variables (see issue #23880).
 
 #![allow(unused)]
-struct Foo<X> { x: Box<X> }
+struct Foo<X> {
+    x: Box<X>,
+}
 impl<Bar> Foo<Bar> {
     fn foo(&self) {
         type Bar = i32;
diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs
index 4c28568a739..01fed8537d0 100644
--- a/tests/ui/simd/intrinsic/float-math-pass.rs
+++ b/tests/ui/simd/intrinsic/float-math-pass.rs
@@ -85,6 +85,9 @@ fn main() {
         let r = simd_round(h);
         assert_eq!(x, r);
 
+        let r = simd_round_ties_even(h);
+        assert_eq!(z, r);
+
         let r = simd_trunc(h);
         assert_eq!(z, r);
     }
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
index fdf06b7882e..caec607d6fe 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
@@ -43,6 +43,10 @@ fn main() {
         simd_shl(y, y);
         simd_shr(x, x);
         simd_shr(y, y);
+        simd_funnel_shl(x, x, x);
+        simd_funnel_shl(y, y, y);
+        simd_funnel_shr(x, x, x);
+        simd_funnel_shr(y, y, y);
         simd_and(x, x);
         simd_and(y, y);
         simd_or(x, x);
@@ -73,6 +77,10 @@ fn main() {
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shr(0, 0);
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_funnel_shl(0, 0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        simd_funnel_shr(0, 0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_and(0, 0);
         //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_or(0, 0);
@@ -95,6 +103,10 @@ fn main() {
         //~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_shr(z, z);
         //~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_funnel_shl(z, z, z);
+        //~^ ERROR unsupported operation on `f32x4` with element `f32`
+        simd_funnel_shr(z, z, z);
+        //~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_and(z, z);
         //~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_or(z, z);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
index 76db6d5328f..a27a8d721fb 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr
@@ -1,147 +1,171 @@
 error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:64:9
+  --> $DIR/generic-arithmetic-2.rs:68:9
    |
 LL |         simd_add(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:66:9
+  --> $DIR/generic-arithmetic-2.rs:70:9
    |
 LL |         simd_sub(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:68:9
+  --> $DIR/generic-arithmetic-2.rs:72:9
    |
 LL |         simd_mul(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:70:9
+  --> $DIR/generic-arithmetic-2.rs:74:9
    |
 LL |         simd_div(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:72:9
+  --> $DIR/generic-arithmetic-2.rs:76:9
    |
 LL |         simd_shl(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:74:9
+  --> $DIR/generic-arithmetic-2.rs:78:9
    |
 LL |         simd_shr(0, 0);
    |         ^^^^^^^^^^^^^^
 
+error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:80:9
+   |
+LL |         simd_funnel_shl(0, 0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-arithmetic-2.rs:82:9
+   |
+LL |         simd_funnel_shr(0, 0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:76:9
+  --> $DIR/generic-arithmetic-2.rs:84:9
    |
 LL |         simd_and(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:78:9
+  --> $DIR/generic-arithmetic-2.rs:86:9
    |
 LL |         simd_or(0, 0);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:80:9
+  --> $DIR/generic-arithmetic-2.rs:88:9
    |
 LL |         simd_xor(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:83:9
+  --> $DIR/generic-arithmetic-2.rs:91:9
    |
 LL |         simd_neg(0);
    |         ^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:85:9
+  --> $DIR/generic-arithmetic-2.rs:93:9
    |
 LL |         simd_bswap(0);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:87:9
+  --> $DIR/generic-arithmetic-2.rs:95:9
    |
 LL |         simd_bitreverse(0);
    |         ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:89:9
+  --> $DIR/generic-arithmetic-2.rs:97:9
    |
 LL |         simd_ctlz(0);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-arithmetic-2.rs:91:9
+  --> $DIR/generic-arithmetic-2.rs:99:9
    |
 LL |         simd_cttz(0);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:94:9
+  --> $DIR/generic-arithmetic-2.rs:102:9
    |
 LL |         simd_shl(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:96:9
+  --> $DIR/generic-arithmetic-2.rs:104:9
    |
 LL |         simd_shr(z, z);
    |         ^^^^^^^^^^^^^^
 
+error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:106:9
+   |
+LL |         simd_funnel_shl(z, z, z);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
+  --> $DIR/generic-arithmetic-2.rs:108:9
+   |
+LL |         simd_funnel_shr(z, z, z);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:98:9
+  --> $DIR/generic-arithmetic-2.rs:110:9
    |
 LL |         simd_and(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:100:9
+  --> $DIR/generic-arithmetic-2.rs:112:9
    |
 LL |         simd_or(z, z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:102:9
+  --> $DIR/generic-arithmetic-2.rs:114:9
    |
 LL |         simd_xor(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:104:9
+  --> $DIR/generic-arithmetic-2.rs:116:9
    |
 LL |         simd_bswap(z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:106:9
+  --> $DIR/generic-arithmetic-2.rs:118:9
    |
 LL |         simd_bitreverse(z);
    |         ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:108:9
+  --> $DIR/generic-arithmetic-2.rs:120:9
    |
 LL |         simd_ctlz(z);
    |         ^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ctpop` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:110:9
+  --> $DIR/generic-arithmetic-2.rs:122:9
    |
 LL |         simd_ctpop(z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/generic-arithmetic-2.rs:112:9
+  --> $DIR/generic-arithmetic-2.rs:124:9
    |
 LL |         simd_cttz(z);
    |         ^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: aborting due to 28 previous errors
 
 For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
index 3f0325d690b..4c97fb2141d 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
@@ -83,6 +83,80 @@ fn main() {
         all_eq!(simd_shr(simd_shl(y1, y2), y2), y1);
         all_eq!(simd_shr(simd_shl(y2, y1), y1), y2);
 
+        all_eq!(
+            simd_funnel_shl(x1, x2, x1),
+            i32x4([
+                (1 << 1) | (2 >> 31),
+                (2 << 2) | (3 >> 30),
+                (3 << 3) | (4 >> 29),
+                (4 << 4) | (5 >> 28)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shl(x2, x1, x1),
+            i32x4([
+                (2 << 1) | (1 >> 31),
+                (3 << 2) | (2 >> 30),
+                (4 << 3) | (3 >> 29),
+                (5 << 4) | (4 >> 28)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shl(y1, y2, y1),
+            U32::<4>([
+                (1 << 1) | (2 >> 31),
+                (2 << 2) | (3 >> 30),
+                (3 << 3) | (4 >> 29),
+                (4 << 4) | (5 >> 28)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shl(y2, y1, y1),
+            U32::<4>([
+                (2 << 1) | (1 >> 31),
+                (3 << 2) | (2 >> 30),
+                (4 << 3) | (3 >> 29),
+                (5 << 4) | (4 >> 28)
+            ])
+        );
+
+        all_eq!(
+            simd_funnel_shr(x1, x2, x1),
+            i32x4([
+                (1 << 31) | (2 >> 1),
+                (2 << 30) | (3 >> 2),
+                (3 << 29) | (4 >> 3),
+                (4 << 28) | (5 >> 4)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shr(x2, x1, x1),
+            i32x4([
+                (2 << 31) | (1 >> 1),
+                (3 << 30) | (2 >> 2),
+                (4 << 29) | (3 >> 3),
+                (5 << 28) | (4 >> 4)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shr(y1, y2, y1),
+            U32::<4>([
+                (1 << 31) | (2 >> 1),
+                (2 << 30) | (3 >> 2),
+                (3 << 29) | (4 >> 3),
+                (4 << 28) | (5 >> 4)
+            ])
+        );
+        all_eq!(
+            simd_funnel_shr(y2, y1, y1),
+            U32::<4>([
+                (2 << 31) | (1 >> 1),
+                (3 << 30) | (2 >> 2),
+                (4 << 29) | (3 >> 3),
+                (5 << 28) | (4 >> 4)
+            ])
+        );
+
         // ensure we get logical vs. arithmetic shifts correct
         let (a, b, c, d) = (-12, -123, -1234, -12345);
         all_eq!(simd_shr(i32x4([a, b, c, d]), x1), i32x4([a >> 1, b >> 2, c >> 3, d >> 4]));
diff --git a/tests/ui/statics/static-generic-param-soundness.rs b/tests/ui/statics/static-generic-param-soundness.rs
new file mode 100644
index 00000000000..aabcca514d3
--- /dev/null
+++ b/tests/ui/statics/static-generic-param-soundness.rs
@@ -0,0 +1,20 @@
+//! Originally, inner statics in generic functions were generated only once, causing the same
+//! static to be shared across all generic instantiations. This created a soundness hole where
+//! different types could be coerced through thread-local storage in safe code.
+//!
+//! This test checks that generic parameters from outer scopes cannot be used in inner statics,
+//! preventing this soundness issue.
+//!
+//! See https://github.com/rust-lang/rust/issues/9186
+
+enum Bar<T> {
+    //~^ ERROR parameter `T` is never used
+    What,
+}
+
+fn foo<T>() {
+    static a: Bar<T> = Bar::What;
+    //~^ ERROR can't use generic parameters from outer item
+}
+
+fn main() {}
diff --git a/tests/ui/inner-static-type-parameter.stderr b/tests/ui/statics/static-generic-param-soundness.stderr
index 88d33b44c59..47554c7fcb0 100644
--- a/tests/ui/inner-static-type-parameter.stderr
+++ b/tests/ui/statics/static-generic-param-soundness.stderr
@@ -1,5 +1,5 @@
 error[E0401]: can't use generic parameters from outer item
-  --> $DIR/inner-static-type-parameter.rs:6:19
+  --> $DIR/static-generic-param-soundness.rs:16:19
    |
 LL | fn foo<T>() {
    |        - type parameter from outer item
@@ -9,9 +9,9 @@ LL |     static a: Bar<T> = Bar::What;
    = note: a `static` is a separate item from the item that contains it
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/inner-static-type-parameter.rs:3:10
+  --> $DIR/static-generic-param-soundness.rs:10:10
    |
-LL | enum Bar<T> { What }
+LL | enum Bar<T> {
    |          ^ unused type parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
diff --git a/tests/ui/test-attrs/test-function-elided-no-main.rs b/tests/ui/test-attrs/test-function-elided-no-main.rs
new file mode 100644
index 00000000000..97654581567
--- /dev/null
+++ b/tests/ui/test-attrs/test-function-elided-no-main.rs
@@ -0,0 +1,8 @@
+//! Test that #[test] functions are elided when not running tests, causing missing main error
+
+#[test]
+fn main() {
+    // This function would normally serve as main, but since it's marked with #[test],
+    // it gets elided when not running tests
+}
+//~^ ERROR `main` function not found in crate `test_function_elided_no_main`
diff --git a/tests/ui/test-attrs/test-function-elided-no-main.stderr b/tests/ui/test-attrs/test-function-elided-no-main.stderr
new file mode 100644
index 00000000000..0bae690be2b
--- /dev/null
+++ b/tests/ui/test-attrs/test-function-elided-no-main.stderr
@@ -0,0 +1,9 @@
+error[E0601]: `main` function not found in crate `test_function_elided_no_main`
+  --> $DIR/test-function-elided-no-main.rs:7:2
+   |
+LL | }
+   |  ^ consider adding a `main` function to `$DIR/test-function-elided-no-main.rs`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/tests/ui/impl-unused-tps.rs b/tests/ui/traits/constrained-type-params-trait-impl.rs
index a5836db3c8e..301bbdb2ccb 100644
--- a/tests/ui/impl-unused-tps.rs
+++ b/tests/ui/traits/constrained-type-params-trait-impl.rs
@@ -1,3 +1,11 @@
+//! Comprehensive test for type parameter constraints in trait implementations
+//!
+//! This tests various scenarios of type parameter usage in trait implementations:
+//! - Properly constrained parameters through trait bounds
+//! - Unconstrained parameters that should cause compilation errors
+//! - Complex constraint scenarios with `where` clauses and associated types
+//! - Conflicting implementations detection
+
 trait Foo<A> {
     fn get(&self, A: &A) {}
 }
@@ -7,34 +15,34 @@ trait Bar {
 }
 
 impl<T> Foo<T> for [isize; 0] {
-    // OK, T is used in `Foo<T>`.
+    // OK: T is used in the trait bound `Foo<T>`
 }
 
 impl<T, U> Foo<T> for [isize; 1] {
     //~^ ERROR the type parameter `U` is not constrained
+    // T is constrained by `Foo<T>`, but U is completely unused
 }
 
 impl<T, U> Foo<T> for [isize; 2]
 where
     T: Bar<Out = U>,
 {
-    // OK, `U` is now constrained by the output type parameter.
+    // OK: T is constrained by `Foo<T>`, U is constrained by the where clause
 }
 
 impl<T: Bar<Out = U>, U> Foo<T> for [isize; 3] {
-    // OK, same as above but written differently.
+    // OK: Same as above but using bound syntax instead of where clause
 }
 
 impl<T, U> Foo<T> for U {
     //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
+    // This conflicts with the first impl when U = [isize; 0]
 }
 
 impl<T, U> Bar for T {
     //~^ ERROR the type parameter `U` is not constrained
-
     type Out = U;
-
-    // Using `U` in an associated type within the impl is not good enough!
+    // Using U only in associated type definition is insufficient for constraint
 }
 
 impl<T, U> Bar for T
@@ -43,7 +51,7 @@ where
 {
     //~^^^^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates
     //~| ERROR conflicting implementations of trait `Bar`
-    // This crafty self-referential attempt is still no good.
+    // Self-referential constraint doesn't properly constrain U
 }
 
 impl<T, U, V> Foo<T> for T
@@ -53,9 +61,7 @@ where
     //~^^^^ ERROR the type parameter `U` is not constrained
     //~| ERROR the type parameter `V` is not constrained
     //~| ERROR conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]`
-
-    // Here, `V` is bound by an output type parameter, but the inputs
-    // are not themselves constrained.
+    // V is bound through output type, but U and V are not properly constrained as inputs
 }
 
 impl<T, U, V> Foo<(T, U)> for T
@@ -63,7 +69,7 @@ where
     (T, U): Bar<Out = V>,
 {
     //~^^^^ ERROR conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]`
-    // As above, but both T and U ARE constrained.
+    // Both T and U are constrained through `Foo<(T, U)>`, but creates conflicting impl
 }
 
 fn main() {}
diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/traits/constrained-type-params-trait-impl.stderr
index eff5ffff9b6..2175129a8df 100644
--- a/tests/ui/impl-unused-tps.stderr
+++ b/tests/ui/traits/constrained-type-params-trait-impl.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
-  --> $DIR/impl-unused-tps.rs:28:1
+  --> $DIR/constrained-type-params-trait-impl.rs:37:1
    |
 LL | impl<T> Foo<T> for [isize; 0] {
    | ----------------------------- first implementation here
@@ -8,7 +8,7 @@ LL | impl<T, U> Foo<T> for U {
    | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
 
 error[E0119]: conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]`
-  --> $DIR/impl-unused-tps.rs:49:1
+  --> $DIR/constrained-type-params-trait-impl.rs:57:1
    |
 LL |   impl<T> Foo<T> for [isize; 0] {
    |   ----------------------------- first implementation here
@@ -19,7 +19,7 @@ LL | |     (T, U): Bar<Out = V>,
    | |_________________________^ conflicting implementation for `[isize; 0]`
 
 error[E0119]: conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]`
-  --> $DIR/impl-unused-tps.rs:61:1
+  --> $DIR/constrained-type-params-trait-impl.rs:67:1
    |
 LL |   impl<T> Foo<T> for [isize; 0] {
    |   ----------------------------- first implementation here
@@ -30,37 +30,37 @@ LL | |     (T, U): Bar<Out = V>,
    | |_________________________^ conflicting implementation for `[isize; 0]`
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:13:9
+  --> $DIR/constrained-type-params-trait-impl.rs:21:9
    |
 LL | impl<T, U> Foo<T> for [isize; 1] {
    |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:32:9
+  --> $DIR/constrained-type-params-trait-impl.rs:42:9
    |
 LL | impl<T, U> Bar for T {
    |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:40:9
+  --> $DIR/constrained-type-params-trait-impl.rs:48:9
    |
 LL | impl<T, U> Bar for T
    |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:49:9
+  --> $DIR/constrained-type-params-trait-impl.rs:57:9
    |
 LL | impl<T, U, V> Foo<T> for T
    |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:49:12
+  --> $DIR/constrained-type-params-trait-impl.rs:57:12
    |
 LL | impl<T, U, V> Foo<T> for T
    |            ^ unconstrained type parameter
 
 error[E0119]: conflicting implementations of trait `Bar`
-  --> $DIR/impl-unused-tps.rs:40:1
+  --> $DIR/constrained-type-params-trait-impl.rs:48:1
    |
 LL |   impl<T, U> Bar for T {
    |   -------------------- first implementation here
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.rs b/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs
index b1d4b261bab..f5f66ca69cf 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.rs
+++ b/tests/ui/traits/dispatch-from-dyn-invalid-impls.rs
@@ -1,20 +1,30 @@
+//! Test various invalid implementations of DispatchFromDyn trait.
+//!
+//! DispatchFromDyn is a special trait used by the compiler for dyn-compatible dynamic dispatch.
+//! This checks that the compiler correctly rejects invalid implementations:
+//! - Structs with extra non-coercible fields
+//! - Structs with multiple pointer fields
+//! - Structs with no coercible fields
+//! - Structs with repr(C) or other incompatible representations
+//! - Structs with over-aligned fields
+
 #![feature(unsize, dispatch_from_dyn)]
 
-use std::{
-    ops::DispatchFromDyn,
-    marker::{Unsize, PhantomData},
-};
+use std::marker::{PhantomData, Unsize};
+use std::ops::DispatchFromDyn;
 
+// Extra field prevents DispatchFromDyn
 struct WrapperWithExtraField<T>(T, i32);
 
 impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
 //~^ ERROR [E0378]
 where
-    T: DispatchFromDyn<U>,
-{}
-
+    T: DispatchFromDyn<U>
+{
+}
 
-struct MultiplePointers<T: ?Sized>{
+// Multiple pointer fields create ambiguous coercion
+struct MultiplePointers<T: ?Sized> {
     ptr1: *const T,
     ptr2: *const T,
 }
@@ -22,10 +32,11 @@ struct MultiplePointers<T: ?Sized>{
 impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
 //~^ ERROR implementing `DispatchFromDyn` does not allow multiple fields to be coerced
 where
-    T: Unsize<U>,
-{}
-
+    T: Unsize<U>
+{
+}
 
+// No coercible fields (only PhantomData)
 struct NothingToCoerce<T: ?Sized> {
     data: PhantomData<T>,
 }
@@ -33,23 +44,28 @@ struct NothingToCoerce<T: ?Sized> {
 impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
 //~^ ERROR implementing `DispatchFromDyn` requires a field to be coerced
 
+// repr(C) is incompatible with DispatchFromDyn
 #[repr(C)]
 struct HasReprC<T: ?Sized>(Box<T>);
 
 impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
 //~^ ERROR [E0378]
 where
-    T: Unsize<U>,
-{}
+    T: Unsize<U>
+{
+}
 
+// Over-aligned fields are incompatible
 #[repr(align(64))]
 struct OverAlignedZst;
+
 struct OverAligned<T: ?Sized>(Box<T>, OverAlignedZst);
 
 impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
 //~^ ERROR [E0378]
-    where
-        T: Unsize<U>,
-{}
+where
+    T: Unsize<U>
+{
+}
 
 fn main() {}
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr
index 93ec6bbe089..676da0ce81f 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr
+++ b/tests/ui/traits/dispatch-from-dyn-invalid-impls.stderr
@@ -1,25 +1,25 @@
 error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:10:1
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:19:1
    |
 LL | / impl<T, U> DispatchFromDyn<WrapperWithExtraField<U>> for WrapperWithExtraField<T>
 LL | |
 LL | | where
-LL | |     T: DispatchFromDyn<U>,
-   | |__________________________^
+LL | |     T: DispatchFromDyn<U>
+   | |_________________________^
    |
    = note: extra field `1` of type `i32` is not allowed
 
 error[E0375]: implementing `DispatchFromDyn` does not allow multiple fields to be coerced
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:22:1
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:32:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for MultiplePointers<T>
 LL | |
 LL | | where
-LL | |     T: Unsize<U>,
-   | |_________________^
+LL | |     T: Unsize<U>
+   | |________________^
    |
 note: the trait `DispatchFromDyn` may only be implemented when a single field is being coerced
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:18:5
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:28:5
    |
 LL |     ptr1: *const T,
    |     ^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     ptr2: *const T,
    |     ^^^^^^^^^^^^^^
 
 error[E0374]: implementing `DispatchFromDyn` requires a field to be coerced
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:33:1
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:44:1
    |
 LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,22 +35,22 @@ LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingT
    = note: expected a single field to be coerced, none found
 
 error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:39:1
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:51:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<HasReprC<U>> for HasReprC<T>
 LL | |
 LL | | where
-LL | |     T: Unsize<U>,
-   | |_________________^
+LL | |     T: Unsize<U>
+   | |________________^
 
 error[E0378]: the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
-  --> $DIR/invalid_dispatch_from_dyn_impls.rs:49:1
+  --> $DIR/dispatch-from-dyn-invalid-impls.rs:64:1
    |
 LL | / impl<T: ?Sized, U: ?Sized> DispatchFromDyn<OverAligned<U>> for OverAligned<T>
 LL | |
-LL | |     where
-LL | |         T: Unsize<U>,
-   | |_____________________^
+LL | | where
+LL | |     T: Unsize<U>
+   | |________________^
    |
    = note: extra field `1` of type `OverAlignedZst` is not allowed
 
diff --git a/tests/ui/issue-11881.rs b/tests/ui/traits/encoder-trait-bounds-regression.rs
index 1abe0797203..292b921cdf7 100644
--- a/tests/ui/issue-11881.rs
+++ b/tests/ui/traits/encoder-trait-bounds-regression.rs
@@ -1,14 +1,23 @@
+//! Regression test for issue #11881
+//!
+//! Originally, the compiler would ICE when trying to parameterize on certain encoder types
+//! due to issues with higher-ranked trait bounds and lifetime inference. This test checks
+//! that various encoder patterns work correctly:
+//! - Generic encoders with associated error types
+//! - Higher-ranked trait bounds (for<'r> Encodable<JsonEncoder<'r>>)
+//! - Multiple encoder implementations for the same type
+//! - Polymorphic encoding functions
+
 //@ run-pass
 
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
-use std::fmt;
-use std::io::prelude::*;
 use std::io::Cursor;
-use std::slice;
+use std::io::prelude::*;
 use std::marker::PhantomData;
+use std::{fmt, slice};
 
 trait Encoder {
     type Error;
@@ -45,7 +54,6 @@ impl Encoder for OpaqueEncoder {
     type Error = ();
 }
 
-
 struct Foo {
     baz: bool,
 }
@@ -69,7 +77,6 @@ impl<S: Encoder> Encodable<S> for Bar {
 enum WireProtocol {
     JSON,
     Opaque,
-    // ...
 }
 
 fn encode_json<T: for<'a> Encodable<JsonEncoder<'a>>>(val: &T, wr: &mut Cursor<Vec<u8>>) {
diff --git a/tests/ui/traits/eval-caching-error-region.rs b/tests/ui/traits/eval-caching-error-region.rs
new file mode 100644
index 00000000000..831b5ab80c1
--- /dev/null
+++ b/tests/ui/traits/eval-caching-error-region.rs
@@ -0,0 +1,23 @@
+// Regression test for #132882.
+
+use std::ops::Add;
+
+pub trait Numoid: Sized
+where
+    &'missing Self: Add<Self>,
+    //~^ ERROR use of undeclared lifetime name `'missing`
+{
+}
+
+// Proving `N: Numoid`'s well-formedness causes us to have to prove `&'missing N: Add<N>`.
+// Since `'missing` is a region error, that will lead to us consider the predicate to hold,
+// since it references errors. Since the freshener turns error regions into fresh regions,
+// this means that subsequent lookups of `&'?0 N: Add<N>` will also hit this cache entry
+// even if candidate assembly can't assemble anything for `&'?0 N: Add<?1>` anyways. This
+// led to an ICE.
+pub fn compute<N: Numoid>(a: N) {
+    let _ = &a + a;
+    //~^ ERROR cannot add `N` to `&N`
+}
+
+fn main() {}
diff --git a/tests/ui/traits/eval-caching-error-region.stderr b/tests/ui/traits/eval-caching-error-region.stderr
new file mode 100644
index 00000000000..6365d242d2e
--- /dev/null
+++ b/tests/ui/traits/eval-caching-error-region.stderr
@@ -0,0 +1,33 @@
+error[E0261]: use of undeclared lifetime name `'missing`
+  --> $DIR/eval-caching-error-region.rs:7:6
+   |
+LL |     &'missing Self: Add<Self>,
+   |      ^^^^^^^^ undeclared lifetime
+   |
+   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the bound lifetime-generic with a new `'missing` lifetime
+   |
+LL |     for<'missing> &'missing Self: Add<Self>,
+   |     +++++++++++++
+help: consider introducing lifetime `'missing` here
+   |
+LL | pub trait Numoid<'missing>: Sized
+   |                 ++++++++++
+
+error[E0369]: cannot add `N` to `&N`
+  --> $DIR/eval-caching-error-region.rs:19:16
+   |
+LL |     let _ = &a + a;
+   |             -- ^ - N
+   |             |
+   |             &N
+   |
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | pub fn compute<N: Numoid>(a: N) where &N: Add<N> {
+   |                                 ++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0261, E0369.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs
new file mode 100644
index 00000000000..04963c98765
--- /dev/null
+++ b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs
@@ -0,0 +1,18 @@
+//! Test that ?Trait bounds are forbidden in supertraits and trait object types.
+//!
+//! While `?Sized` and other maybe bounds are allowed in type parameter bounds and where clauses,
+//! they are explicitly forbidden in certain syntactic positions:
+//! - As supertraits in trait definitions
+//! - In trait object type expressions
+//!
+//! See https://github.com/rust-lang/rust/issues/20503
+
+trait Tr: ?Sized {}
+//~^ ERROR `?Trait` is not permitted in supertraits
+
+type A1 = dyn Tr + (?Sized);
+//~^ ERROR `?Trait` is not permitted in trait object types
+type A2 = dyn for<'a> Tr + (?Sized);
+//~^ ERROR `?Trait` is not permitted in trait object types
+
+fn main() {}
diff --git a/tests/ui/maybe-bounds.stderr b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr
index 230d11fd0ae..bd0baa580bd 100644
--- a/tests/ui/maybe-bounds.stderr
+++ b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr
@@ -1,5 +1,5 @@
 error[E0658]: `?Trait` is not permitted in supertraits
-  --> $DIR/maybe-bounds.rs:1:11
+  --> $DIR/maybe-trait-bounds-forbidden-locations.rs:10:11
    |
 LL | trait Tr: ?Sized {}
    |           ^^^^^^
@@ -9,7 +9,7 @@ LL | trait Tr: ?Sized {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `?Trait` is not permitted in trait object types
-  --> $DIR/maybe-bounds.rs:4:20
+  --> $DIR/maybe-trait-bounds-forbidden-locations.rs:13:20
    |
 LL | type A1 = dyn Tr + (?Sized);
    |                    ^^^^^^^^
@@ -18,7 +18,7 @@ LL | type A1 = dyn Tr + (?Sized);
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `?Trait` is not permitted in trait object types
-  --> $DIR/maybe-bounds.rs:6:28
+  --> $DIR/maybe-trait-bounds-forbidden-locations.rs:15:28
    |
 LL | type A2 = dyn for<'a> Tr + (?Sized);
    |                            ^^^^^^^^
diff --git a/tests/ui/transmute/diverging-fn-transmute.rs b/tests/ui/transmute/diverging-fn-transmute.rs
new file mode 100644
index 00000000000..aca82037a0c
--- /dev/null
+++ b/tests/ui/transmute/diverging-fn-transmute.rs
@@ -0,0 +1,10 @@
+//! Regression test for issue #35849: transmute with panic in diverging function
+
+fn assert_sizeof() -> ! {
+    unsafe {
+        ::std::mem::transmute::<f64, [u8; 8]>(panic!())
+        //~^ ERROR mismatched types
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/diverging-fn-tail-35849.stderr b/tests/ui/transmute/diverging-fn-transmute.stderr
index 614f9b9cb5d..b9aeae7ed62 100644
--- a/tests/ui/diverging-fn-tail-35849.stderr
+++ b/tests/ui/transmute/diverging-fn-transmute.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/diverging-fn-tail-35849.rs:3:9
+  --> $DIR/diverging-fn-transmute.rs:5:9
    |
 LL | fn assert_sizeof() -> ! {
    |                       - expected `!` because of return type
diff --git a/tests/ui/type-alias-enum-variants/module-type-args-error.rs b/tests/ui/type-alias-enum-variants/module-type-args-error.rs
new file mode 100644
index 00000000000..9f7dae4f4f5
--- /dev/null
+++ b/tests/ui/type-alias-enum-variants/module-type-args-error.rs
@@ -0,0 +1,16 @@
+//! Test that type arguments are properly rejected on modules.
+//!
+//! Related PR: https://github.com/rust-lang/rust/pull/56225 (RFC 2338 implementation)
+
+mod Mod {
+    pub struct FakeVariant<T>(pub T);
+}
+
+fn main() {
+    // This should work fine - normal generic struct constructor
+    Mod::FakeVariant::<i32>(0);
+
+    // This should error - type arguments not allowed on modules
+    Mod::<i32>::FakeVariant(0);
+    //~^ ERROR type arguments are not allowed on module `Mod` [E0109]
+}
diff --git a/tests/ui/mod-subitem-as-enum-variant.stderr b/tests/ui/type-alias-enum-variants/module-type-args-error.stderr
index 92d972eba42..4c59d19eaa7 100644
--- a/tests/ui/mod-subitem-as-enum-variant.stderr
+++ b/tests/ui/type-alias-enum-variants/module-type-args-error.stderr
@@ -1,5 +1,5 @@
 error[E0109]: type arguments are not allowed on module `Mod`
-  --> $DIR/mod-subitem-as-enum-variant.rs:7:11
+  --> $DIR/module-type-args-error.rs:14:11
    |
 LL |     Mod::<i32>::FakeVariant(0);
    |     ---   ^^^ type argument not allowed