From 71c39dea4d18373e4da35838332071562ea44d33 Mon Sep 17 00:00:00 2001 From: Andreas Molzer Date: Fri, 21 Oct 2022 14:05:45 +0200 Subject: [PATCH 1/2] Argument type for mutable with_metadata_of (#75091) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The method takes two pointer arguments: one `self` supplying the pointer value, and a second pointer supplying the metadata. The new parameter type more clearly reflects the actual requirements. The provenance of the metadata parameter is disregarded completely. Using a mutable pointer in the call site can be coerced to a const pointer while the reverse is not true. An example of the current use: ```rust // Manually taking an unsized object from a `ManuallyDrop` into another allocation. let val: &core::mem::ManuallyDrop = …; let ptr = val as *const _ as *mut T; let ptr = uninit.as_ptr().with_metadata_of(ptr); ``` This could then instead be simplified to: ```rust // Manually taking an unsized object from a `ManuallyDrop` into another allocation. let val: &core::mem::ManuallyDrop = …; let ptr = uninit.as_ptr().with_metadata_of(&**val); ``` --- library/core/src/ptr/mut_ptr.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index bbcc7c699e036..0bb2566fd4c98 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -80,10 +80,14 @@ impl *mut T { #[unstable(feature = "set_ptr_value", issue = "75091")] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] - pub fn with_metadata_of(self, mut val: *mut U) -> *mut U + pub fn with_metadata_of(self, val: *const U) -> *mut U where U: ?Sized, { + // Prepare in the type system that we will replace the pointer value with a mutable + // pointer, taking the mutable provenance from the `self` pointer. + let mut val = val as *mut U; + // Pointer to the pointer value within the value. let target = &mut val as *mut *mut U as *mut *mut u8; // SAFETY: In case of a thin pointer, this operations is identical // to a simple assignment. In case of a fat pointer, with the current From e3606b2b0298be6122d002257b50ba42f0b4d4d2 Mon Sep 17 00:00:00 2001 From: Andreas Molzer Date: Fri, 21 Oct 2022 14:34:16 +0200 Subject: [PATCH 2/2] Reduce mutability in std-use of with_metadata_of --- library/alloc/src/rc.rs | 2 +- library/alloc/src/sync.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 6d247681c6661..9c229665c7e91 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1386,7 +1386,7 @@ impl Rc { Self::allocate_for_layout( Layout::for_value(&*ptr), |layout| Global.allocate(layout), - |mem| mem.with_metadata_of(ptr as *mut RcBox), + |mem| mem.with_metadata_of(ptr as *const RcBox), ) } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index df315dad89324..e8d9de4fb3ce5 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1204,7 +1204,7 @@ impl Arc { Self::allocate_for_layout( Layout::for_value(&*ptr), |layout| Global.allocate(layout), - |mem| mem.with_metadata_of(ptr as *mut ArcInner), + |mem| mem.with_metadata_of(ptr as *const ArcInner), ) } }