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](cad93775eb).
```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?
This commit is contained in:
commit
b22559f547
3 changed files with 7 additions and 3 deletions
|
|
@ -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>),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue