diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index bbd20899a18e1..99c70332e91fd 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -160,6 +160,7 @@ #![feature(maybe_uninit_uninit_array)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] +#![feature(set_ptr_value)] #![feature(slice_ptr_get)] #![feature(slice_split_at_unchecked)] #![feature(str_internals)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index e28ddf3c75ea8..bff270b787ece 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -79,19 +79,14 @@ impl *const T { /// } /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] + #[rustc_const_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: *const U) -> *const U + pub const fn with_metadata_of(self, meta: *const U) -> *const U where U: ?Sized, { - let target = &mut val as *mut *const U as *mut *const 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 - // fat pointer layout implementation, the first field of such a - // pointer is always the data pointer, which is likewise assigned. - unsafe { *target = self as *const u8 }; - val + from_raw_parts::(self as *const (), metadata(meta)) } /// Changes constness without changing the type. @@ -478,8 +473,7 @@ impl *const T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. - let this = unsafe { self.cast::().offset(count).cast::<()>() }; - from_raw_parts::(this, metadata(self)) + unsafe { self.cast::().offset(count).with_metadata_of(self) } } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -559,7 +553,7 @@ impl *const T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_offset(self, count: isize) -> Self { - from_raw_parts::(self.cast::().wrapping_offset(count).cast::<()>(), metadata(self)) + self.cast::().wrapping_offset(count).with_metadata_of(self) } /// Masks out bits of the pointer according to a mask. @@ -597,8 +591,7 @@ impl *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] pub fn mask(self, mask: usize) -> *const T { - let this = intrinsics::ptr_mask(self.cast::<()>(), mask); - from_raw_parts::(this, metadata(self)) + intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self) } /// Calculates the distance between two pointers. The returned value is in @@ -939,8 +932,7 @@ impl *const T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. - let this = unsafe { self.cast::().add(count).cast::<()>() }; - from_raw_parts::(this, metadata(self)) + unsafe { self.cast::().add(count).with_metadata_of(self) } } /// Calculates the offset from a pointer (convenience for @@ -1026,8 +1018,7 @@ impl *const T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. - let this = unsafe { self.cast::().sub(count).cast::<()>() }; - from_raw_parts::(this, metadata(self)) + unsafe { self.cast::().sub(count).with_metadata_of(self) } } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -1107,7 +1098,7 @@ impl *const T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_add(self, count: usize) -> Self { - from_raw_parts::(self.cast::().wrapping_add(count).cast::<()>(), metadata(self)) + self.cast::().wrapping_add(count).with_metadata_of(self) } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -1187,7 +1178,7 @@ impl *const T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_sub(self, count: usize) -> Self { - from_raw_parts::(self.cast::().wrapping_sub(count).cast::<()>(), metadata(self)) + self.cast::().wrapping_sub(count).with_metadata_of(self) } /// Reads the value from `self` without moving it. This leaves the diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index ba21126dbd2ca..8f4809ec4baa4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -78,23 +78,14 @@ impl *mut T { /// } /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] + #[rustc_const_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, val: *const U) -> *mut U + pub const fn with_metadata_of(self, meta: *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 - // fat pointer layout implementation, the first field of such a - // pointer is always the data pointer, which is likewise assigned. - unsafe { *target = self as *mut u8 }; - val + from_raw_parts_mut::(self as *mut (), metadata(meta)) } /// Changes constness without changing the type. @@ -496,8 +487,7 @@ impl *mut T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. - let this = unsafe { self.cast::().offset(count).cast::<()>() }; - from_raw_parts_mut::(this, metadata(self)) + unsafe { self.cast::().offset(count).with_metadata_of(self) } } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -576,10 +566,7 @@ impl *mut T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_offset(self, count: isize) -> Self { - from_raw_parts_mut::( - self.cast::().wrapping_offset(count).cast::<()>(), - metadata(self), - ) + self.cast::().wrapping_offset(count).with_metadata_of(self) } /// Masks out bits of the pointer according to a mask. @@ -620,8 +607,7 @@ impl *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[inline(always)] pub fn mask(self, mask: usize) -> *mut T { - let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut (); - from_raw_parts_mut::(this, metadata(self)) + intrinsics::ptr_mask(self.cast::<()>(), mask).cast_mut().with_metadata_of(self) } /// Returns `None` if the pointer is null, or else returns a unique reference to @@ -1048,8 +1034,7 @@ impl *mut T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. - let this = unsafe { self.cast::().add(count).cast::<()>() }; - from_raw_parts_mut::(this, metadata(self)) + unsafe { self.cast::().add(count).with_metadata_of(self) } } /// Calculates the offset from a pointer (convenience for @@ -1135,8 +1120,7 @@ impl *mut T { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. - let this = unsafe { self.cast::().sub(count).cast::<()>() }; - from_raw_parts_mut::(this, metadata(self)) + unsafe { self.cast::().sub(count).with_metadata_of(self) } } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -1216,7 +1200,7 @@ impl *mut T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_add(self, count: usize) -> Self { - from_raw_parts_mut::(self.cast::().wrapping_add(count).cast::<()>(), metadata(self)) + self.cast::().wrapping_add(count).with_metadata_of(self) } /// Calculates the offset from a pointer using wrapping arithmetic. @@ -1296,7 +1280,7 @@ impl *mut T { #[unstable(feature = "pointer_byte_offsets", issue = "96283")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")] pub const fn wrapping_byte_sub(self, count: usize) -> Self { - from_raw_parts_mut::(self.cast::().wrapping_sub(count).cast::<()>(), metadata(self)) + self.cast::().wrapping_sub(count).with_metadata_of(self) } /// Reads the value from `self` without moving it. This leaves the