about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock55
-rw-r--r--RELEASES.md114
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_const_eval/messages.ftl4
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs12
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs3
-rw-r--r--compiler/rustc_passes/src/stability.rs3
-rw-r--r--library/core/src/mem/mod.rs2
-rw-r--r--library/profiler_builtins/build.rs60
-rw-r--r--src/bootstrap/src/core/sanity.rs9
-rw-r--r--src/librustdoc/html/static/js/main.js10
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs68
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/lib.rs3
-rw-r--r--src/tools/miri/src/machine.rs25
-rw-r--r--src/tools/miri/src/shims/native_lib.rs13
-rw-r--r--src/tools/miri/tests/native-lib/native-lib.map (renamed from src/tools/miri/tests/native-lib/libtest.map)8
-rw-r--r--src/tools/miri/tests/native-lib/pass/ptr_read_access.rs82
-rw-r--r--src/tools/miri/tests/native-lib/pass/ptr_read_access.stdout1
-rw-r--r--src/tools/miri/tests/native-lib/pass/scalar_arguments.rs (renamed from src/tools/miri/tests/native-lib/pass/call_extern_c_fn.rs)0
-rw-r--r--src/tools/miri/tests/native-lib/pass/scalar_arguments.stdout (renamed from src/tools/miri/tests/native-lib/pass/call_extern_c_fn.stdout)0
-rw-r--r--src/tools/miri/tests/native-lib/ptr_read_access.c47
-rw-r--r--src/tools/miri/tests/native-lib/scalar_arguments.c (renamed from src/tools/miri/tests/native-lib/test.c)0
-rw-r--r--src/tools/miri/tests/ui.rs13
-rw-r--r--src/tools/opt-dist/src/tests.rs8
-rw-r--r--src/tools/run-make-support/Cargo.toml2
-rw-r--r--src/tools/tidy/src/features.rs3
-rw-r--r--src/tools/tidy/src/target_specific_tests.rs10
-rw-r--r--tests/crashes/129425.rs6
-rw-r--r--tests/crashes/129444.rs15
-rw-r--r--tests/crashes/129503.rs7
-rw-r--r--tests/crashes/129556.rs26
-rw-r--r--tests/run-make/print-cfg/rmake.rs5
-rw-r--r--tests/run-make/print-target-list/rmake.rs13
-rw-r--r--tests/run-make/print-to-output/rmake.rs10
-rw-r--r--tests/run-make/target-without-atomic-cas/rmake.rs15
-rw-r--r--tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr4
37 files changed, 559 insertions, 101 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6ea4cd8f5ac..23c7a5bc60f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2463,7 +2463,7 @@ dependencies = [
  "indexmap",
  "memchr",
  "ruzstd 0.7.0",
- "wasmparser",
+ "wasmparser 0.215.0",
 ]
 
 [[package]]
@@ -3133,7 +3133,7 @@ dependencies = [
  "regex",
  "serde_json",
  "similar",
- "wasmparser",
+ "wasmparser 0.216.0",
 ]
 
 [[package]]
@@ -5779,9 +5779,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasi-preview1-component-adapter-provider"
-version = "23.0.2"
+version = "24.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91d3d13afef569b9fc80cfbb807c87c16ef49bd3ac1a93285ea6a264b600d2d"
+checksum = "36e6cadfa74538edd5409b6f8c79628436529138e9618b7373bec7aae7805835"
 
 [[package]]
 name = "wasm-bindgen"
@@ -5840,16 +5840,16 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
 
 [[package]]
 name = "wasm-component-ld"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51449c63d1ce69f92b8465a084ed5b91f1a7eb583fa95796650a6bfcffc4f9cb"
+checksum = "13261270d3ac58ffae0219ae34f297a7e24f9ee3b13b29be579132c588a83519"
 dependencies = [
  "anyhow",
  "clap",
  "lexopt",
  "tempfile",
  "wasi-preview1-component-adapter-provider",
- "wasmparser",
+ "wasmparser 0.216.0",
  "wat",
  "wit-component",
  "wit-parser",
@@ -5864,19 +5864,19 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.215.0"
+version = "0.216.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb56df3e06b8e6b77e37d2969a50ba51281029a9aeb3855e76b7f49b6418847"
+checksum = "04c23aebea22c8a75833ae08ed31ccc020835b12a41999e58c31464271b94a88"
 dependencies = [
  "leb128",
- "wasmparser",
+ "wasmparser 0.216.0",
 ]
 
 [[package]]
 name = "wasm-metadata"
-version = "0.215.0"
+version = "0.216.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c6bb07c5576b608f7a2a9baa2294c1a3584a249965d695a9814a496cb6d232f"
+checksum = "47c8154d703a6b0e45acf6bd172fa002fc3c7058a9f7615e517220aeca27c638"
 dependencies = [
  "anyhow",
  "indexmap",
@@ -5885,7 +5885,7 @@ dependencies = [
  "serde_json",
  "spdx",
  "wasm-encoder",
- "wasmparser",
+ "wasmparser 0.216.0",
 ]
 
 [[package]]
@@ -5894,6 +5894,15 @@ version = "0.215.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53fbde0881f24199b81cf49b6ff8f9c145ac8eb1b7fc439adb5c099734f7d90e"
 dependencies = [
+ "bitflags 2.6.0",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.216.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcdee6bea3619d311fb4b299721e89a986c3470f804b6d534340e412589028e3"
+dependencies = [
  "ahash",
  "bitflags 2.6.0",
  "hashbrown",
@@ -5904,9 +5913,9 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "215.0.0"
+version = "216.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ff1d00d893593249e60720be04a7c1f42f1c4dc3806a2869f4e66ab61eb54cb"
+checksum = "f7eb1f2eecd913fdde0dc6c3439d0f24530a98ac6db6cb3d14d92a5328554a08"
 dependencies = [
  "bumpalo",
  "leb128",
@@ -5917,9 +5926,9 @@ dependencies = [
 
 [[package]]
 name = "wat"
-version = "1.215.0"
+version = "1.216.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "670bf4d9c8cf76ae242d70ded47c546525b6dafaa6871f9bcb065344bf2b4e3d"
+checksum = "ac0409090fb5154f95fb5ba3235675fd9e579e731524d63b6a2f653e1280c82a"
 dependencies = [
  "wast",
 ]
@@ -6206,9 +6215,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.215.0"
+version = "0.216.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f725e3885fc5890648be5c5cbc1353b755dc932aa5f1aa7de968b912a3280743"
+checksum = "7e2ca3ece38ea2447a9069b43074ba73d96dde1944cba276c54e41371745f9dc"
 dependencies = [
  "anyhow",
  "bitflags 2.6.0",
@@ -6219,15 +6228,15 @@ dependencies = [
  "serde_json",
  "wasm-encoder",
  "wasm-metadata",
- "wasmparser",
+ "wasmparser 0.216.0",
  "wit-parser",
 ]
 
 [[package]]
 name = "wit-parser"
-version = "0.215.0"
+version = "0.216.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "935a97eaffd57c3b413aa510f8f0b550a4a9fe7d59e79cd8b89a83dcb860321f"
+checksum = "a4d108165c1167a4ccc8a803dcf5c28e0a51d6739fd228cc7adce768632c764c"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -6238,7 +6247,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser",
+ "wasmparser 0.216.0",
 ]
 
 [[package]]
diff --git a/RELEASES.md b/RELEASES.md
index 5e4827be4ec..6aba476103e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,117 @@
+Version 1.81.0 (2024-09-05)
+==========================
+
+<a id="1.81.0-Language"></a>
+
+Language
+--------
+
+- [Abort on uncaught panics in `extern "C"` functions.](https://github.com/rust-lang/rust/pull/116088/)
+- [Fix ambiguous cases of multiple `&` in elided self lifetimes.](https://github.com/rust-lang/rust/pull/117967/)
+- [Stabilize `#[expect]` for lints (RFC 2383),](https://github.com/rust-lang/rust/pull/120924/) like `#[allow]` with a warning if the lint is _not_ fulfilled.
+- [Change method resolution to constrain hidden types instead of rejecting method candidates.](https://github.com/rust-lang/rust/pull/123962/)
+- [Bump `elided_lifetimes_in_associated_constant` to deny.](https://github.com/rust-lang/rust/pull/124211/)
+- [`offset_from`: always allow pointers to point to the same address.](https://github.com/rust-lang/rust/pull/124921/)
+- [Allow constraining opaque types during subtyping in the trait system.](https://github.com/rust-lang/rust/pull/125447/)
+- [Allow constraining opaque types during various unsizing casts.](https://github.com/rust-lang/rust/pull/125610/)
+- [Deny keyword lifetimes pre-expansion.](https://github.com/rust-lang/rust/pull/126762/)
+
+<a id="1.81.0-Compiler"></a>
+
+Compiler
+--------
+
+- [Make casts of pointers to trait objects stricter.](https://github.com/rust-lang/rust/pull/120248/)
+- [Check alias args for well-formedness even if they have escaping bound vars.](https://github.com/rust-lang/rust/pull/123737/)
+- [Deprecate no-op codegen option `-Cinline-threshold=...`.](https://github.com/rust-lang/rust/pull/124712/)
+- [Re-implement a type-size based limit.](https://github.com/rust-lang/rust/pull/125507/)
+- [Properly account for alignment in `transmute` size checks.](https://github.com/rust-lang/rust/pull/125740/)
+- [Remove the `box_pointers` lint.](https://github.com/rust-lang/rust/pull/126018/)
+- [Ensure the interpreter checks bool/char for validity when they are used in a cast.](https://github.com/rust-lang/rust/pull/126265/)
+- [Improve coverage instrumentation for functions containing nested items.](https://github.com/rust-lang/rust/pull/127199/)
+- Target changes:
+  - [Add Tier 3 `no_std` Xtensa targets:](https://github.com/rust-lang/rust/pull/125141/) `xtensa-esp32-none-elf`, `xtensa-esp32s2-none-elf`, `xtensa-esp32s3-none-elf`
+  - [Add Tier 3 `std` Xtensa targets:](https://github.com/rust-lang/rust/pull/126380/) `xtensa-esp32-espidf`, `xtensa-esp32s2-espidf`, `xtensa-esp32s3-espidf`
+  - [Add Tier 3 i686 Redox OS target:](https://github.com/rust-lang/rust/pull/126192/) `i686-unknown-redox`
+  - [Promote `arm64ec-pc-windows-msvc` to Tier 2.](https://github.com/rust-lang/rust/pull/126039/)
+  - [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/)
+  - [Promote `loongarch64-unknown-linux-musl` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/126298/)
+  - [Enable full tools and profiler for LoongArch Linux targets.](https://github.com/rust-lang/rust/pull/127078/)
+  - [Unconditionally warn on usage of `wasm32-wasi`.](https://github.com/rust-lang/rust/pull/126662/) (see compatibility note below)
+  - Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support.
+
+<a id="1.81.0-Libraries"></a>
+
+Libraries
+---------
+
+- [Split core's `PanicInfo` and std's `PanicInfo`.](https://github.com/rust-lang/rust/pull/115974/) (see compatibility note below)
+- [Generalize `{Rc,Arc}::make_mut()` to unsized types.](https://github.com/rust-lang/rust/pull/116113/)
+- [Replace sort implementations with stable `driftsort` and unstable `ipnsort`.](https://github.com/rust-lang/rust/pull/124032/) All `slice::sort*` and `slice::select_nth*` methods are expected to see significant performance improvements. See the [research project](https://github.com/Voultapher/sort-research-rs) for more details.
+- [Document behavior of `create_dir_all` with respect to empty paths.](https://github.com/rust-lang/rust/pull/125112/)
+- [Fix interleaved output in the default panic hook when multiple threads panic simultaneously.](https://github.com/rust-lang/rust/pull/127397/)
+
+<a id="1.81.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`core::error`](https://doc.rust-lang.org/stable/core/error/index.html)
+- [`hint::assert_unchecked`](https://doc.rust-lang.org/stable/core/hint/fn.assert_unchecked.html)
+- [`fs::exists`](https://doc.rust-lang.org/stable/std/fs/fn.exists.html)
+- [`AtomicBool::fetch_not`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicBool.html#method.fetch_not)
+- [`Duration::abs_diff`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.abs_diff)
+- [`IoSlice::advance`](https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance)
+- [`IoSlice::advance_slices`](https://doc.rust-lang.org/stable/std/io/struct.IoSlice.html#method.advance_slices)
+- [`IoSliceMut::advance`](https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance)
+- [`IoSliceMut::advance_slices`](https://doc.rust-lang.org/stable/std/io/struct.IoSliceMut.html#method.advance_slices)
+- [`PanicHookInfo`](https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html)
+- [`PanicInfo::message`](https://doc.rust-lang.org/stable/core/panic/struct.PanicInfo.html#method.message)
+- [`PanicMessage`](https://doc.rust-lang.org/stable/core/panic/struct.PanicMessage.html)
+
+These APIs are now stable in const contexts:
+
+- [`char::from_u32_unchecked`](https://doc.rust-lang.org/stable/core/char/fn.from_u32_unchecked.html) (function)
+- [`char::from_u32_unchecked`](https://doc.rust-lang.org/stable/core/primitive.char.html#method.from_u32_unchecked) (method)
+- [`CStr::count_bytes`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.count_bytes)
+- [`CStr::from_ptr`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.from_ptr)
+
+<a id="1.81.0-Cargo"></a>
+
+Cargo
+-----
+
+- [Generated `.cargo_vcs_info.json` is always included, even when `--allow-dirty` is passed.](https://github.com/rust-lang/cargo/pull/13960/)
+- [Disallow `package.license-file` and `package.readme` pointing to non-existent files during packaging.](https://github.com/rust-lang/cargo/pull/13921/)
+- [Disallow passing `--release`/`--debug` flag along with the `--profile` flag.](https://github.com/rust-lang/cargo/pull/13971/)
+- [Remove `lib.plugin` key support in `Cargo.toml`. Rust plugin support has been deprecated for four years and was removed in 1.75.0.](https://github.com/rust-lang/cargo/pull/13902/)
+
+<a id="1.81.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+
+* Usage of the `wasm32-wasi` target will now issue a compiler warning and request users switch to the `wasm32-wasip1` target instead. Both targets are the same, `wasm32-wasi` is only being renamed, and this [change to the WASI target](https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html) is being done to enable removing `wasm32-wasi` in January 2025.
+
+* We have renamed `std::panic::PanicInfo` to `std::panic::PanicHookInfo`. The old name will continue to work as an alias, but will result in a deprecation warning starting in Rust 1.82.0.
+
+  `core::panic::PanicInfo` will remain unchanged, however, as this is now a *different type*.
+ 
+  The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`.
+
+* The new sort implementations may panic if a type's implementation of [`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) (or the given comparison function) does not implement a [total order](https://en.wikipedia.org/wiki/Total_order) as the trait requires. `Ord`'s supertraits (`PartialOrd`, `Eq`, and `PartialEq`) must also be consistent. The previous implementations would not "notice" any problem, but the new implementations have a good chance of detecting inconsistencies, throwing a panic rather than returning knowingly unsorted data.
+
+<a id="1.81.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Add a Rust-for Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/)
+
 Version 1.80.0 (2024-07-25)
 ==========================
 
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index e78039bafd8..3ab4cd0a0f5 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -41,7 +41,7 @@ tempfile = "3.2"
 thin-vec = "0.2.12"
 thorin-dwp = "0.7"
 tracing = "0.1"
-wasm-encoder = "0.215.0"
+wasm-encoder = "0.216.0"
 # tidy-alphabetical-end
 
 [target.'cfg(unix)'.dependencies]
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index db788b6b151..8a6dfb89249 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -415,8 +415,8 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
 
 const_eval_unstable_in_stable =
     const-stable function cannot use `#[feature({$gate})]`
-    .unstable_sugg = if it is not part of the public API, make this function unstably const
-    .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
+    .unstable_sugg = if the function is not (yet) meant to be stable, make this function unstably const
+    .bypass_sugg = otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
 
 const_eval_unterminated_c_string =
     reading a null-terminated string starting at {$pointer} with no null found before end of allocation
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 88453245b84..6cfd7be48e6 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -362,17 +362,7 @@ pub trait Machine<'tcx>: Sized {
         ecx: &InterpCx<'tcx, Self>,
         id: AllocId,
         alloc: &'b Allocation,
-    ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
-    {
-        // The default implementation does a copy; CTFE machines have a more efficient implementation
-        // based on their particular choice for `Provenance`, `AllocExtra`, and `Bytes`.
-        let kind = Self::GLOBAL_KIND
-            .expect("if GLOBAL_KIND is None, adjust_global_allocation must be overwritten");
-        let alloc = alloc.adjust_from_tcx(&ecx.tcx, |ptr| ecx.global_root_pointer(ptr))?;
-        let extra =
-            Self::init_alloc_extra(ecx, id, MemoryKind::Machine(kind), alloc.size(), alloc.align)?;
-        Ok(Cow::Owned(alloc.with_extra(extra)))
-    }
+    ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
 
     /// Initialize the extra state of an allocation.
     ///
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 3e101c0c635..5fb8af576ae 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -358,10 +358,11 @@ impl Allocation {
     pub fn adjust_from_tcx<Prov: Provenance, Bytes: AllocBytes, Err>(
         &self,
         cx: &impl HasDataLayout,
+        mut alloc_bytes: impl FnMut(&[u8], Align) -> Result<Bytes, Err>,
         mut adjust_ptr: impl FnMut(Pointer<CtfeProvenance>) -> Result<Pointer<Prov>, Err>,
     ) -> Result<Allocation<Prov, (), Bytes>, Err> {
         // Copy the data.
-        let mut bytes = Bytes::from_bytes(Cow::Borrowed(&*self.bytes), self.align);
+        let mut bytes = alloc_bytes(&*self.bytes, self.align)?;
         // Adjust provenance of pointers stored in this allocation.
         let mut new_provenance = Vec::with_capacity(self.provenance.ptrs().len());
         let ptr_size = cx.data_layout().pointer_size.bytes_usize();
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 4d58590ca3b..ba4c300ea61 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -544,9 +544,8 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
         let is_stable =
             self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable());
         let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none();
-        let is_reachable = self.effective_visibilities.is_reachable(def_id);
 
-        if is_const && is_stable && missing_const_stability_attribute && is_reachable {
+        if is_const && is_stable && missing_const_stability_attribute {
             let descr = self.tcx.def_descr(def_id.to_def_id());
             self.tcx.dcx().emit_err(errors::MissingConstStabAttr { span, descr });
         }
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index e602b497d17..fed484ae3cd 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -612,7 +612,7 @@ pub const fn needs_drop<T: ?Sized>() -> bool {
 ///
 /// There is no guarantee that an all-zero byte-pattern represents a valid value
 /// of some type `T`. For example, the all-zero byte-pattern is not a valid value
-/// for reference types (`&T`, `&mut T`) and functions pointers. Using `zeroed`
+/// for reference types (`&T`, `&mut T`) and function pointers. Using `zeroed`
 /// on such types causes immediate [undefined behavior][ub] because [the Rust
 /// compiler assumes][inv] that there always is a valid value in a variable it
 /// considers initialized.
diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index c1e0e5c1c89..dd85239fa8c 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -1,14 +1,15 @@
 //! Compiles the profiler part of the `compiler-rt` library.
 //!
-//! See the build.rs for libcompiler_builtins crate for details.
+//! Loosely based on:
+//! - LLVM's `compiler-rt/lib/profile/CMakeLists.txt`
+//! - <https://github.com/rust-lang/compiler-builtins/blob/master/build.rs>.
 
 use std::env;
 use std::path::PathBuf;
 
 fn main() {
-    println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB");
-    if let Ok(rt) = env::var("LLVM_PROFILER_RT_LIB") {
-        println!("cargo:rustc-link-lib=static:+verbatim={rt}");
+    if let Ok(rt) = tracked_env_var("LLVM_PROFILER_RT_LIB") {
+        println!("cargo::rustc-link-lib=static:+verbatim={rt}");
         return;
     }
 
@@ -16,13 +17,13 @@ fn main() {
     let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
     let cfg = &mut cc::Build::new();
 
-    // FIXME: `rerun-if-changed` directives are not currently emitted and the build script
-    // will not rerun on changes in these source files or headers included into them.
-    let mut profile_sources = vec![
+    let profile_sources = vec![
+        // tidy-alphabetical-start
         "GCDAProfiling.c",
         "InstrProfiling.c",
         "InstrProfilingBuffer.c",
         "InstrProfilingFile.c",
+        "InstrProfilingInternal.c",
         "InstrProfilingMerge.c",
         "InstrProfilingMergeFile.c",
         "InstrProfilingNameVar.c",
@@ -37,15 +38,13 @@ fn main() {
         "InstrProfilingValue.c",
         "InstrProfilingVersionVar.c",
         "InstrProfilingWriter.c",
-        // These files were added in LLVM 11.
-        "InstrProfilingInternal.c",
-        "InstrProfilingBiasVar.c",
+        "WindowsMMap.c",
+        // tidy-alphabetical-end
     ];
 
     if target_env == "msvc" {
         // Don't pull in extra libraries on MSVC
         cfg.flag("/Zl");
-        profile_sources.push("WindowsMMap.c");
         cfg.define("strdup", Some("_strdup"));
         cfg.define("open", Some("_open"));
         cfg.define("fdopen", Some("_fdopen"));
@@ -60,8 +59,6 @@ fn main() {
         if target_os != "windows" {
             cfg.flag("-fvisibility=hidden");
             cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
-        } else {
-            profile_sources.push("WindowsMMap.c");
         }
     }
 
@@ -80,26 +77,33 @@ fn main() {
     }
 
     // Get the LLVM `compiler-rt` directory from bootstrap.
-    println!("cargo:rerun-if-env-changed=RUST_COMPILER_RT_FOR_PROFILER");
-    let root = PathBuf::from(env::var("RUST_COMPILER_RT_FOR_PROFILER").unwrap_or_else(|_| {
-        let path = "../../src/llvm-project/compiler-rt";
-        println!("RUST_COMPILER_RT_FOR_PROFILER was not set; falling back to {path:?}");
-        path.to_owned()
-    }));
+    let root = PathBuf::from(tracked_env_var_or_fallback(
+        "RUST_COMPILER_RT_FOR_PROFILER",
+        "../../src/llvm-project/compiler-rt",
+    ));
 
     let src_root = root.join("lib").join("profile");
     assert!(src_root.exists(), "profiler runtime source directory not found: {src_root:?}");
-    let mut n_sources_found = 0u32;
-    for src in profile_sources {
-        let path = src_root.join(src);
-        if path.exists() {
-            cfg.file(path);
-            n_sources_found += 1;
-        }
+    println!("cargo::rerun-if-changed={}", src_root.display());
+    for file in profile_sources {
+        cfg.file(src_root.join(file));
     }
-    assert!(n_sources_found > 0, "couldn't find any profiler runtime source files in {src_root:?}");
 
-    cfg.include(root.join("include"));
+    let include = root.join("include");
+    println!("cargo::rerun-if-changed={}", include.display());
+    cfg.include(include);
+
     cfg.warnings(false);
     cfg.compile("profiler-rt");
 }
+
+fn tracked_env_var(key: &str) -> Result<String, env::VarError> {
+    println!("cargo::rerun-if-env-changed={key}");
+    env::var(key)
+}
+fn tracked_env_var_or_fallback(key: &str, fallback: &str) -> String {
+    tracked_env_var(key).unwrap_or_else(|_| {
+        println!("cargo::warning={key} was not set; falling back to {fallback:?}");
+        fallback.to_owned()
+    })
+}
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index c42d4c56c38..60ec57d0d44 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -8,9 +8,7 @@
 //! In theory if we get past this phase it's a bug if a build fails, but in
 //! practice that's likely not true!
 
-use std::collections::HashMap;
-#[cfg(not(feature = "bootstrap-self-test"))]
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 use std::ffi::{OsStr, OsString};
 use std::path::PathBuf;
 use std::{env, fs};
@@ -34,7 +32,6 @@ pub struct Finder {
 // it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
 //
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
-#[cfg(not(feature = "bootstrap-self-test"))]
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
 ];
@@ -205,7 +202,6 @@ than building it.
         .map(|p| cmd_finder.must_have(p))
         .or_else(|| cmd_finder.maybe_have("reuse"));
 
-    #[cfg(not(feature = "bootstrap-self-test"))]
     let stage0_supported_target_list: HashSet<String> = crate::utils::helpers::output(
         command(&build.config.initial_rustc).args(["--print", "target-list"]).as_command_mut(),
     )
@@ -234,8 +230,7 @@ than building it.
         }
 
         // Ignore fake targets that are only used for unit tests in bootstrap.
-        #[cfg(not(feature = "bootstrap-self-test"))]
-        {
+        if cfg!(not(feature = "bootstrap-self-test")) && !skip_target_sanity {
             let mut has_target = false;
             let target_str = target.to_string();
 
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 75f2a1418cd..c3e219f2c87 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1878,9 +1878,15 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         if (elem === null) {
             return;
         }
-        const buttons = elem.querySelector(".button-holder");
+        let buttons = elem.querySelector(".button-holder");
         if (buttons === null) {
-            return;
+            // On mobile, you can't hover an element so buttons need to be created on click
+            // if they're not already there.
+            addCopyButton(event);
+            buttons = elem.querySelector(".button-holder");
+            if (buttons === null) {
+                return;
+            }
         }
         buttons.classList.toggle("keep-visible");
     }
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index ed955e78c3e..76c68add8cd 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -42,6 +42,11 @@ pub struct GlobalStateInner {
     /// they do not have an `AllocExtra`.
     /// This is the inverse of `int_to_ptr_map`.
     base_addr: FxHashMap<AllocId, u64>,
+    /// Temporarily store prepared memory space for global allocations the first time their memory
+    /// address is required. This is used to ensure that the memory is allocated before Miri assigns
+    /// it an internal address, which is important for matching the internal address to the machine
+    /// address so FFI can read from pointers.
+    prepared_alloc_bytes: FxHashMap<AllocId, MiriAllocBytes>,
     /// A pool of addresses we can reuse for future allocations.
     reuse: ReusePool,
     /// Whether an allocation has been exposed or not. This cannot be put
@@ -59,6 +64,7 @@ impl VisitProvenance for GlobalStateInner {
         let GlobalStateInner {
             int_to_ptr_map: _,
             base_addr: _,
+            prepared_alloc_bytes: _,
             reuse: _,
             exposed: _,
             next_base_addr: _,
@@ -78,6 +84,7 @@ impl GlobalStateInner {
         GlobalStateInner {
             int_to_ptr_map: Vec::default(),
             base_addr: FxHashMap::default(),
+            prepared_alloc_bytes: FxHashMap::default(),
             reuse: ReusePool::new(config),
             exposed: FxHashSet::default(),
             next_base_addr: stack_addr,
@@ -166,7 +173,39 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 assert!(!matches!(kind, AllocKind::Dead));
 
                 // This allocation does not have a base address yet, pick or reuse one.
-                let base_addr = if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
+                let base_addr = if ecx.machine.native_lib.is_some() {
+                    // In native lib mode, we use the "real" address of the bytes for this allocation.
+                    // This ensures the interpreted program and native code have the same view of memory.
+                    match kind {
+                        AllocKind::LiveData => {
+                            let ptr = if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
+                                // For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
+                                let prepared_bytes = MiriAllocBytes::zeroed(size, align)
+                                    .unwrap_or_else(|| {
+                                        panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes")
+                                    });
+                                let ptr = prepared_bytes.as_ptr();
+                                    // Store prepared allocation space to be picked up for use later.
+                                    global_state.prepared_alloc_bytes.try_insert(alloc_id, prepared_bytes).unwrap();
+                                ptr
+                            } else {
+                                ecx.get_alloc_bytes_unchecked_raw(alloc_id)?
+                            };
+                            // Ensure this pointer's provenance is exposed, so that it can be used by FFI code.
+                            ptr.expose_provenance().try_into().unwrap()
+                        }
+                        AllocKind::Function | AllocKind::VTable => {
+                            // Allocate some dummy memory to get a unique address for this function/vtable.
+                            let alloc_bytes = MiriAllocBytes::from_bytes(&[0u8; 1], Align::from_bytes(1).unwrap());
+                            // We don't need to expose these bytes as nobody is allowed to access them.
+                            let addr = alloc_bytes.as_ptr().addr().try_into().unwrap();
+                            // Leak the underlying memory to ensure it remains unique.
+                            std::mem::forget(alloc_bytes);
+                            addr
+                        }
+                        AllocKind::Dead => unreachable!()
+                    }
+                } else if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(                    
                     &mut *rng,
                     size,
                     align,
@@ -318,6 +357,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         Ok(base_ptr.wrapping_offset(offset, ecx))
     }
 
+    // This returns some prepared `MiriAllocBytes`, either because `addr_from_alloc_id` reserved
+    // memory space in the past, or by doing the pre-allocation right upon being called.
+    fn get_global_alloc_bytes(&self, id: AllocId, kind: MemoryKind, bytes: &[u8], align: Align) -> InterpResult<'tcx, MiriAllocBytes> {
+        let ecx = self.eval_context_ref();
+        Ok(if ecx.machine.native_lib.is_some() {
+            // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`.
+            // This additional call ensures that some `MiriAllocBytes` are always prepared.
+            ecx.addr_from_alloc_id(id, kind)?;
+            let mut global_state = ecx.machine.alloc_addresses.borrow_mut();
+            // The memory we need here will have already been allocated during an earlier call to
+            // `addr_from_alloc_id` for this allocation. So don't create a new `MiriAllocBytes` here, instead
+            // fetch the previously prepared bytes from `prepared_alloc_bytes`.
+            let mut prepared_alloc_bytes = global_state
+                .prepared_alloc_bytes
+                .remove(&id)
+                .unwrap_or_else(|| panic!("alloc bytes for {id:?} have not been prepared"));
+            // Sanity-check that the prepared allocation has the right size and alignment.
+            assert!(prepared_alloc_bytes.as_ptr().is_aligned_to(align.bytes_usize()));
+            assert_eq!(prepared_alloc_bytes.len(), bytes.len());
+            // Copy allocation contents into prepared memory.
+            prepared_alloc_bytes.copy_from_slice(bytes);
+            prepared_alloc_bytes
+        } else {
+            MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(&*bytes), align)
+        })
+    }
+
     /// When a pointer is used for a memory access, this computes where in which allocation the
     /// access is going.
     fn ptr_get_alloc(
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 87ce4c0c931..79f292f6965 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -889,7 +889,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             let alloc = this.ctfe_query(|tcx| tcx.eval_static_initializer(def_id))?;
             // We make a full copy of this allocation.
             let mut alloc =
-                alloc.inner().adjust_from_tcx(&this.tcx, |ptr| this.global_root_pointer(ptr))?;
+                alloc.inner().adjust_from_tcx(&this.tcx, |bytes, align| Ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align)), |ptr| this.global_root_pointer(ptr))?;
             // This allocation will be deallocated when the thread dies, so it is not in read-only memory.
             alloc.mutability = Mutability::Mut;
             // Create a fresh allocation with this content.
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index ece393caf9a..8a59206943d 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -12,6 +12,9 @@
 #![feature(let_chains)]
 #![feature(trait_upcasting)]
 #![feature(strict_overflow_ops)]
+#![feature(strict_provenance)]
+#![feature(exposed_provenance)]
+#![feature(pointer_is_aligned_to)]
 // Configure clippy and other lints
 #![allow(
     clippy::collapsible_else_if,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 264b7b269de..66c6966d1a6 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1,6 +1,7 @@
 //! Global machine state as well as implementation of the interpreter engine
 //! `Machine` trait.
 
+use std::borrow::Cow;
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::fmt;
@@ -1261,6 +1262,30 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         })
     }
 
+    /// Called to adjust global allocations to the Provenance and AllocExtra of this machine.
+    ///
+    /// If `alloc` contains pointers, then they are all pointing to globals.
+    ///
+    /// This should avoid copying if no work has to be done! If this returns an owned
+    /// allocation (because a copy had to be done to adjust things), machine memory will
+    /// cache the result. (This relies on `AllocMap::get_or` being able to add the
+    /// owned allocation to the map even when the map is shared.)
+    fn adjust_global_allocation<'b>(
+        ecx: &InterpCx<'tcx, Self>,
+        id: AllocId,
+        alloc: &'b Allocation,
+    ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>
+    {
+        let kind = Self::GLOBAL_KIND.unwrap().into();
+        let alloc = alloc.adjust_from_tcx(&ecx.tcx,
+            |bytes, align| ecx.get_global_alloc_bytes(id, kind, bytes, align),
+            |ptr| ecx.global_root_pointer(ptr),
+        )?;
+        let extra =
+            Self::init_alloc_extra(ecx, id, kind, alloc.size(), alloc.align)?;
+        Ok(Cow::Owned(alloc.with_extra(extra)))
+    }
+
     #[inline(always)]
     fn before_memory_read(
         _tcx: TyCtxtAt<'tcx>,
diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs
index 40697e17ba1..25d96fbd733 100644
--- a/src/tools/miri/src/shims/native_lib.rs
+++ b/src/tools/miri/src/shims/native_lib.rs
@@ -194,6 +194,8 @@ enum CArg {
     UInt64(u64),
     /// usize.
     USize(usize),
+    /// Raw pointer, stored as C's `void*`.
+    RawPtr(*mut std::ffi::c_void),
 }
 
 impl<'a> CArg {
@@ -210,6 +212,7 @@ impl<'a> CArg {
             CArg::UInt32(i) => ffi::arg(i),
             CArg::UInt64(i) => ffi::arg(i),
             CArg::USize(i) => ffi::arg(i),
+            CArg::RawPtr(i) => ffi::arg(i),
         }
     }
 }
@@ -234,6 +237,16 @@ fn imm_to_carg<'tcx>(v: ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'t
         ty::Uint(UintTy::U64) => CArg::UInt64(v.to_scalar().to_u64()?),
         ty::Uint(UintTy::Usize) =>
             CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()),
+        ty::RawPtr(_, mutability) => {
+            // Arbitrary mutable pointer accesses are not currently supported in Miri.
+            if mutability.is_mut() {
+                throw_unsup_format!("unsupported mutable pointer type for native call: {}", v.layout.ty);
+            } else {
+                let s = v.to_scalar().to_pointer(cx)?.addr();
+                // This relies on the `expose_provenance` in `addr_from_alloc_id`.
+                CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
+            }
+        },
         _ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),
     })
 }
diff --git a/src/tools/miri/tests/native-lib/libtest.map b/src/tools/miri/tests/native-lib/native-lib.map
index a57a4dc149f..7e3bd19622a 100644
--- a/src/tools/miri/tests/native-lib/libtest.map
+++ b/src/tools/miri/tests/native-lib/native-lib.map
@@ -1,12 +1,20 @@
 CODEABI_1.0 {
     # Define which symbols to export.
     global:
+        # scalar_arguments.c
         add_one_int;
         printer;
         test_stack_spill;
         get_unsigned_int;
         add_int16;
         add_short_to_long;
+
+        # ptr_read_access.c
+        print_pointer;
+        access_simple;
+        access_nested;
+        access_static;
+
     # The rest remains private.
     local: *;
 };
diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.rs b/src/tools/miri/tests/native-lib/pass/ptr_read_access.rs
new file mode 100644
index 00000000000..d8e6209839e
--- /dev/null
+++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.rs
@@ -0,0 +1,82 @@
+//@only-target-linux
+//@only-on-host
+
+fn main() {
+    test_pointer();
+
+    test_simple();
+
+    test_nested();
+
+    test_static();
+}
+
+// Test void function that dereferences a pointer and prints its contents from C.
+fn test_pointer() {
+    extern "C" {
+        fn print_pointer(ptr: *const i32);
+    }
+
+    let x = 42;
+
+    unsafe { print_pointer(&x) };
+}
+
+// Test function that dereferences a simple struct pointer and accesses a field.
+fn test_simple() {
+    #[repr(C)]
+    struct Simple {
+        field: i32
+    }
+
+    extern "C" {
+        fn access_simple(s_ptr: *const Simple) -> i32;
+    }
+
+    let simple = Simple { field: -42 };
+
+    assert_eq!(unsafe { access_simple(&simple) }, -42);
+}
+
+// Test function that dereferences nested struct pointers and accesses fields.
+fn test_nested() {
+    use std::ptr::NonNull;
+    
+    #[derive(Debug, PartialEq, Eq)]
+    #[repr(C)]
+    struct Nested {
+        value: i32,
+        next: Option<NonNull<Nested>>,
+    }
+
+    extern "C" {
+        fn access_nested(n_ptr: *const Nested) -> i32;
+    }
+
+    let mut nested_0 = Nested { value: 97, next: None };
+    let mut nested_1 = Nested { value: 98, next: NonNull::new(&mut nested_0) };
+    let nested_2 = Nested { value: 99, next: NonNull::new(&mut nested_1) };
+
+    assert_eq!(unsafe { access_nested(&nested_2) }, 97);
+}
+
+// Test function that dereferences static struct pointers and accesses fields.
+fn test_static() {
+
+    #[repr(C)]
+    struct Static {
+        value: i32,
+        recurse: &'static Static,
+    }
+
+    extern "C" {
+        fn access_static(n_ptr: *const Static) -> i32;
+    }
+    
+    static STATIC: Static = Static {
+        value: 9001,
+        recurse: &STATIC,
+    };
+
+    assert_eq!(unsafe { access_static(&STATIC) }, 9001);
+}
diff --git a/src/tools/miri/tests/native-lib/pass/ptr_read_access.stdout b/src/tools/miri/tests/native-lib/pass/ptr_read_access.stdout
new file mode 100644
index 00000000000..1a8799abfc9
--- /dev/null
+++ b/src/tools/miri/tests/native-lib/pass/ptr_read_access.stdout
@@ -0,0 +1 @@
+printing pointer dereference from C: 42
diff --git a/src/tools/miri/tests/native-lib/pass/call_extern_c_fn.rs b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs
index 1e1d0b11e99..1e1d0b11e99 100644
--- a/src/tools/miri/tests/native-lib/pass/call_extern_c_fn.rs
+++ b/src/tools/miri/tests/native-lib/pass/scalar_arguments.rs
diff --git a/src/tools/miri/tests/native-lib/pass/call_extern_c_fn.stdout b/src/tools/miri/tests/native-lib/pass/scalar_arguments.stdout
index 7ba13d2d7b0..7ba13d2d7b0 100644
--- a/src/tools/miri/tests/native-lib/pass/call_extern_c_fn.stdout
+++ b/src/tools/miri/tests/native-lib/pass/scalar_arguments.stdout
diff --git a/src/tools/miri/tests/native-lib/ptr_read_access.c b/src/tools/miri/tests/native-lib/ptr_read_access.c
new file mode 100644
index 00000000000..03b9189e2e8
--- /dev/null
+++ b/src/tools/miri/tests/native-lib/ptr_read_access.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+/* Test: test_pointer */
+
+void print_pointer(const int *ptr) {
+  printf("printing pointer dereference from C: %d\n", *ptr);
+}
+
+/* Test: test_simple */
+
+typedef struct Simple {
+  int field;
+} Simple;
+
+int access_simple(const Simple *s_ptr) {
+  return s_ptr->field;
+}
+
+/* Test: test_nested */
+
+typedef struct Nested {
+  int value;
+  struct Nested *next;
+} Nested;
+
+// Returns the innermost/last value of a Nested pointer chain.
+int access_nested(const Nested *n_ptr) {
+  // Edge case: `n_ptr == NULL` (i.e. first Nested is None).
+  if (!n_ptr) { return 0; }
+
+  while (n_ptr->next) {
+    n_ptr = n_ptr->next;
+  }
+
+  return n_ptr->value;
+}
+
+/* Test: test_static */
+
+typedef struct Static {
+    int value;
+    struct Static *recurse;
+} Static;
+
+int access_static(const Static *s_ptr) {
+  return s_ptr->recurse->recurse->value;
+}
diff --git a/src/tools/miri/tests/native-lib/test.c b/src/tools/miri/tests/native-lib/scalar_arguments.c
index 68714f1743b..68714f1743b 100644
--- a/src/tools/miri/tests/native-lib/test.c
+++ b/src/tools/miri/tests/native-lib/scalar_arguments.c
diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs
index 9cbcf6e42a7..c510ef95c30 100644
--- a/src/tools/miri/tests/ui.rs
+++ b/src/tools/miri/tests/ui.rs
@@ -36,18 +36,25 @@ fn build_native_lib() -> PathBuf {
     // Create the directory if it does not already exist.
     std::fs::create_dir_all(&so_target_dir)
         .expect("Failed to create directory for shared object file");
-    let so_file_path = so_target_dir.join("libtestlib.so");
+    let so_file_path = so_target_dir.join("native-lib.so");
     let cc_output = Command::new(cc)
         .args([
             "-shared",
             "-o",
             so_file_path.to_str().unwrap(),
-            "tests/native-lib/test.c",
+            // FIXME: Automate gathering of all relevant C source files in the directory.
+            "tests/native-lib/scalar_arguments.c",
+            "tests/native-lib/ptr_read_access.c",
             // Only add the functions specified in libcode.version to the shared object file.
             // This is to avoid automatically adding `malloc`, etc.
             // Source: https://anadoxin.org/blog/control-over-symbol-exports-in-gcc.html/
             "-fPIC",
-            "-Wl,--version-script=tests/native-lib/libtest.map",
+            "-Wl,--version-script=tests/native-lib/native-lib.map",
+            // Ensure we notice serious problems in the C code.
+            "-Wall",
+            "-Wextra",
+            "-Wpedantic",
+            "-Werror",
         ])
         .output()
         .expect("failed to generate shared object file for testing native function calls");
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 30c9648bc08..9dbba7a0500 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -102,7 +102,13 @@ llvm-config = "{llvm_config}"
     for test_path in env.skipped_tests() {
         args.extend(["--skip", test_path]);
     }
-    cmd(&args).env("COMPILETEST_FORCE_STAGE0", "1").run().context("Cannot execute tests")
+    cmd(&args)
+        .env("COMPILETEST_FORCE_STAGE0", "1")
+        // Above we override the stage 0 compiler with previously compiled compiler,
+        // which can cause confusion in bootstrap's target sanity checks.
+        .env("BOOTSTRAP_SKIP_TARGET_SANITY", "1")
+        .run()
+        .context("Cannot execute tests")
 }
 
 /// Tries to find the version of the dist artifacts (either nightly, beta, or 1.XY.Z).
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 77df6e7beb5..d3605cd3dce 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 bstr = "1.6.0"
 object = "0.36.2"
 similar = "2.5.0"
-wasmparser = { version = "0.215", default-features = false, features = ["std"] }
+wasmparser = { version = "0.216", default-features = false, features = ["std"] }
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
 gimli = "0.31.0"
 build_helper = { path = "../build_helper" }
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index a4d27d29d32..4f24eb21242 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -455,9 +455,10 @@ fn get_and_check_lib_features(
                     if f.tracking_issue != s.tracking_issue && f.level != Status::Accepted {
                         tidy_error!(
                             bad,
-                            "{}:{}: `issue` \"{}\" mismatches the {} `issue` of \"{}\"",
+                            "{}:{}: feature gate {} has inconsistent `issue`: \"{}\" mismatches the {} `issue` of \"{}\"",
                             file.display(),
                             line,
+                            name,
                             f.tracking_issue_display(),
                             display,
                             s.tracking_issue_display(),
diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs
index 8be27d1e117..c1032b19f97 100644
--- a/src/tools/tidy/src/target_specific_tests.rs
+++ b/src/tools/tidy/src/target_specific_tests.rs
@@ -36,8 +36,8 @@ struct RevisionInfo<'a> {
     llvm_components: Option<Vec<&'a str>>,
 }
 
-pub fn check(path: &Path, bad: &mut bool) {
-    crate::walk::walk(path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| {
+pub fn check(tests_path: &Path, bad: &mut bool) {
+    crate::walk::walk(tests_path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| {
         let file = entry.path().display();
         let mut header_map = BTreeMap::new();
         iter_header(content, &mut |HeaderLine { revision, directive, .. }| {
@@ -65,6 +65,12 @@ pub fn check(path: &Path, bad: &mut bool) {
                 }
             }
         });
+
+        // Skip run-make tests as revisions are not supported.
+        if entry.path().strip_prefix(tests_path).is_ok_and(|rest| rest.starts_with("run-make")) {
+            return;
+        }
+
         for (rev, RevisionInfo { target_arch, llvm_components }) in &header_map {
             let rev = rev.unwrap_or("[unspecified]");
             match (target_arch, llvm_components) {
diff --git a/tests/crashes/129425.rs b/tests/crashes/129425.rs
new file mode 100644
index 00000000000..ac7dc007847
--- /dev/null
+++ b/tests/crashes/129425.rs
@@ -0,0 +1,6 @@
+//@ known-bug: rust-lang/rust#129425
+
+//@compile-flags: --crate-type=lib
+
+#![feature(generic_const_exprs)]
+fn foo<'a, T: 'a>(_: [(); std::mem::offset_of!((T,), 0)]) {}
diff --git a/tests/crashes/129444.rs b/tests/crashes/129444.rs
new file mode 100644
index 00000000000..b1b547b5191
--- /dev/null
+++ b/tests/crashes/129444.rs
@@ -0,0 +1,15 @@
+//@ known-bug: rust-lang/rust#129444
+
+//@ compile-flags: -Znext-solver=coherence
+
+trait Trait {
+    type Assoc;
+}
+
+struct W<T: Trait>(*mut T);
+impl<T: ?Trait> Trait for W<W<W<T>>> {}
+
+trait NoOverlap {}
+impl<T: Trait<W<T>>> NoOverlap for T {}
+
+impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
diff --git a/tests/crashes/129503.rs b/tests/crashes/129503.rs
new file mode 100644
index 00000000000..c1ed46e5955
--- /dev/null
+++ b/tests/crashes/129503.rs
@@ -0,0 +1,7 @@
+//@ known-bug: rust-lang/rust#129503
+
+use std::arch::asm;
+
+unsafe fn f6() {
+    asm!(concat!(r#"lJ𐏿Æ�.𐏿�"#, "r} {}"));
+}
diff --git a/tests/crashes/129556.rs b/tests/crashes/129556.rs
new file mode 100644
index 00000000000..364827e9444
--- /dev/null
+++ b/tests/crashes/129556.rs
@@ -0,0 +1,26 @@
+//@ known-bug: rust-lang/rust#129556
+
+#![feature(adt_const_params)]
+#![feature(generic_const_exprs)]
+
+use core::marker::ConstParamTy;
+
+// #[derive(ConstParamTy, PartialEq, Eq)]
+// struct StructOrEnum;
+
+#[derive(ConstParamTy, PartialEq, Eq)]
+enum StructOrEnum {
+    A,
+}
+
+trait TraitParent<const SMTH: StructOrEnum = { StructOrEnum::A }> {}
+
+trait TraitChild<const SMTH: StructOrEnum = { StructOrEnum::A }>: TraitParent<SMTH> {}
+
+impl TraitParent for StructOrEnum {}
+
+// ICE occurs
+impl TraitChild for StructOrEnum {}
+
+// ICE does not occur
+// impl TraitChild<{ StructOrEnum::A }> for StructOrEnum {}
diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs
index 471a99b90d9..7b8b760ea33 100644
--- a/tests/run-make/print-cfg/rmake.rs
+++ b/tests/run-make/print-cfg/rmake.rs
@@ -5,6 +5,11 @@
 //!
 //! It also checks that some targets have the correct set cfgs.
 
+// ignore-tidy-linelength
+//@ needs-llvm-components: arm x86
+// Note: without the needs-llvm-components it will fail on LLVM built without the required
+// components listed above.
+
 use std::collections::HashSet;
 use std::iter::FromIterator;
 use std::path::PathBuf;
diff --git a/tests/run-make/print-target-list/rmake.rs b/tests/run-make/print-target-list/rmake.rs
index 743ed52069d..04ef8440104 100644
--- a/tests/run-make/print-target-list/rmake.rs
+++ b/tests/run-make/print-target-list/rmake.rs
@@ -1,10 +1,15 @@
-// Checks that all the targets returned by `rustc --print target-list` are valid
-// target specifications
+// Checks that all the targets returned by `rustc --print target-list` are valid target
+// specifications.
+
+// ignore-tidy-linelength
+//@ needs-llvm-components: aarch64 arm avr bpf csky hexagon loongarch m68k mips msp430 nvptx powerpc riscv sparc systemz webassembly x86
+// FIXME(jieyouxu): there has to be a better way to do this, without the needs-llvm-components it
+// will fail on LLVM built without all of the components listed above.
 
 use run_make_support::bare_rustc;
 
-// FIXME(127877): certain experimental targets fail with creating a 'LLVM TargetMachine'
-// in CI, so we skip them
+// FIXME(#127877): certain experimental targets fail with creating a 'LLVM TargetMachine' in CI, so
+// we skip them.
 const EXPERIMENTAL_TARGETS: &[&str] = &["avr", "m68k", "csky", "xtensa"];
 
 fn main() {
diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs
index db2a291f8e7..a85ab5e23b0 100644
--- a/tests/run-make/print-to-output/rmake.rs
+++ b/tests/run-make/print-to-output/rmake.rs
@@ -1,5 +1,11 @@
-//! This checks the output of some `--print` options when
-//! output to a file (instead of stdout)
+//! This checks the output of some `--print` options when output to a file (instead of stdout)
+
+// ignore-tidy-linelength
+//@ needs-llvm-components: aarch64 arm avr bpf csky hexagon loongarch m68k mips msp430 nvptx powerpc riscv sparc systemz webassembly x86
+// FIXME(jieyouxu): there has to be a better way to do this, without the needs-llvm-components it
+// will fail on LLVM built without all of the components listed above. If adding a new target that
+// relies on a llvm component not listed above, it will need to be added to the required llvm
+// components above.
 
 use std::path::PathBuf;
 
diff --git a/tests/run-make/target-without-atomic-cas/rmake.rs b/tests/run-make/target-without-atomic-cas/rmake.rs
index c8782b6d1a5..e6c86c0c21d 100644
--- a/tests/run-make/target-without-atomic-cas/rmake.rs
+++ b/tests/run-make/target-without-atomic-cas/rmake.rs
@@ -1,8 +1,13 @@
-// ARM Cortex-M are a class of processors supported by the rust compiler. However,
-// they cannot support any atomic features, such as Arc. This test simply prints
-// the configuration details of one Cortex target, and checks that the compiler
-// does not falsely list atomic support.
-// See https://github.com/rust-lang/rust/pull/36874
+// ARM Cortex-M are a class of processors supported by the rust compiler. However, they cannot
+// support any atomic features, such as Arc. This test simply prints the configuration details of
+// one Cortex target, and checks that the compiler does not falsely list atomic support.
+// See <https://github.com/rust-lang/rust/pull/36874>.
+
+// ignore-tidy-linelength
+//@ needs-llvm-components: arm
+// Note: without the needs-llvm-components it will fail on LLVM built without all of the components
+// listed above. If any new targets are added, please double-check their respective llvm components
+// are specified above.
 
 use run_make_support::rustc;
 
diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
index 019deda063c..cb447719f9c 100644
--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
@@ -20,12 +20,12 @@ error: const-stable function cannot use `#[feature(const_refs_to_cell)]`
 LL |     x.get();
    |     ^
    |
-help: if it is not part of the public API, make this function unstably const
+help: if the function is not (yet) meant to be stable, make this function unstably const
    |
 LL + #[rustc_const_unstable(feature = "...", issue = "...")]
 LL | const fn bar3() -> u32 {
    |
-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
    |
 LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)]
 LL | const fn bar3() -> u32 {