From c72a794526efd186066c6bf166ba3c6b5af6a9bf Mon Sep 17 00:00:00 2001 From: Dominik Schwaiger Date: Tue, 14 Jul 2026 20:42:02 +0000 Subject: [PATCH] add rustc_no_writable to mem::forget and structs it uses * add rustc_no_writable no mem::forget and structs it uses * rename test file * apply #[rustc_no_writable] to transmute_prefix and transmute_neo --- library/core/src/mem/manually_drop.rs | 1 + library/core/src/mem/maybe_dangling.rs | 1 + library/core/src/mem/mod.rs | 3 +++ .../mem_forget-implicit_writes.rs | 20 +++++++++++++++++++ 4 files changed, 25 insertions(+) create mode 100644 src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index a70cb8ad67297..6c2f77a373393 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -178,6 +178,7 @@ impl ManuallyDrop { #[stable(feature = "manually_drop", since = "1.20.0")] #[rustc_const_stable(feature = "const_manually_drop", since = "1.32.0")] #[inline(always)] + #[rustc_no_writable] pub const fn new(value: T) -> ManuallyDrop { ManuallyDrop { value: MaybeDangling::new(value) } } diff --git a/library/core/src/mem/maybe_dangling.rs b/library/core/src/mem/maybe_dangling.rs index 7ae1bf899dd4f..46e5228a2da3f 100644 --- a/library/core/src/mem/maybe_dangling.rs +++ b/library/core/src/mem/maybe_dangling.rs @@ -74,6 +74,7 @@ pub struct MaybeDangling(P); impl MaybeDangling

{ /// Wraps a value in a `MaybeDangling`, allowing it to dangle. + #[rustc_no_writable] pub const fn new(x: P) -> Self where P: Sized, diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a00a6c4783ba6..f79f461faf04c 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -186,6 +186,7 @@ pub mod type_info; #[rustc_const_stable(feature = "const_forget", since = "1.46.0")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "mem_forget"] +#[rustc_no_writable] pub const fn forget(t: T) { let _ = ManuallyDrop::new(t); } @@ -1170,6 +1171,7 @@ pub const unsafe fn transmute_copy(src: &Src) -> Dst { /// let _: std::mem::MaybeUninit = unsafe { transmute_prefix(123_u8) }; /// ``` #[unstable(feature = "transmute_prefix", issue = "155079")] +#[rustc_no_writable] pub const unsafe fn transmute_prefix(src: Src) -> Dst { #[repr(C)] union Transmute { @@ -1219,6 +1221,7 @@ pub const unsafe fn transmute_prefix(src: Src) -> Dst { #[unstable(feature = "transmute_neo", issue = "155079")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[inline] +#[rustc_no_writable] pub const unsafe fn transmute_neo(src: Src) -> Dst { const { assert!(Src::SIZE == Dst::SIZE) }; diff --git a/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs b/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs new file mode 100644 index 0000000000000..77cf6997761bb --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/mem_forget-implicit_writes.rs @@ -0,0 +1,20 @@ +// Regression test. This failed before applying `#[rustc_no_writable]` to `mem::forget`, `ManuallyDrop::new`, and `MaybeDangling::new`. +//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes + +use std::mem; + +// This function is taken from the crate `derive_more`, from the file `into.rs` +unsafe fn transmute(from: From) -> To { + let to = unsafe { mem::transmute_copy(&from) }; + mem::forget(from); + to +} + +fn main() { + let mut val = 10u32; + let r: &mut u32 = &mut val; + + let to: &mut i32 = unsafe { transmute(r) }; + + assert_eq!(*to, 10); +}