about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-10-22 16:28:09 +0530
committerGitHub <noreply@github.com>2022-10-22 16:28:09 +0530
commitb22559f547f963df83987dfcf2aeb070a84d42bf (patch)
treeab9cd6ef97c921d201cd06a8fdef3f2390707665
parent3f49f9506f124097b9f773d08248432eca625f1c (diff)
parente3606b2b0298be6122d002257b50ba42f0b4d4d2 (diff)
downloadrust-b22559f547f963df83987dfcf2aeb070a84d42bf.tar.gz
rust-b22559f547f963df83987dfcf2aeb070a84d42bf.zip
Rollup merge of #103346 - HeroicKatora:metadata_of_const_pointer_argument, r=dtolnay
Adjust argument type for mutable with_metadata_of (#75091)

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.

In some cases, the current parameter type can thus lead to a very slightly confusing additional cast. [Example](https://github.com/HeroicKatora/static-alloc/commit/cad93775eb9adc62f744651e3abf19513e69e7d0).

```rust
// Manually taking an unsized object from a `ManuallyDrop` into another allocation.
let val: &core::mem::ManuallyDrop<T> = …;

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<T> = …;

let ptr = uninit.as_ptr().with_metadata_of(&**val);
```

Tracking issue: https://github.com/rust-lang/rust/issues/75091

``@dtolnay`` you're reviewed #95249, would you mind chiming in?
-rw-r--r--library/alloc/src/rc.rs2
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/core/src/ptr/mut_ptr.rs6
3 files changed, 7 insertions, 3 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 6d247681c66..9c229665c7e 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1386,7 +1386,7 @@ impl<T: ?Sized> Rc<T> {
             Self::allocate_for_layout(
                 Layout::for_value(&*ptr),
                 |layout| Global.allocate(layout),
-                |mem| mem.with_metadata_of(ptr as *mut RcBox<T>),
+                |mem| mem.with_metadata_of(ptr as *const RcBox<T>),
             )
         }
     }
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index df315dad893..e8d9de4fb3c 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1204,7 +1204,7 @@ impl<T: ?Sized> Arc<T> {
             Self::allocate_for_layout(
                 Layout::for_value(&*ptr),
                 |layout| Global.allocate(layout),
-                |mem| mem.with_metadata_of(ptr as *mut ArcInner<T>),
+                |mem| mem.with_metadata_of(ptr as *const ArcInner<T>),
             )
         }
     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index bbcc7c699e0..0bb2566fd4c 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -80,10 +80,14 @@ impl<T: ?Sized> *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<U>(self, mut val: *mut U) -> *mut U
+    pub fn with_metadata_of<U>(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