Rollup merge of #103701 - WaffleLapkin:__points-at-implementation__--this-can-be-simplified, r=scottmcm
Simplify some pointer method implementations - Make `pointer::with_metadata_of` const (+simplify implementation) (cc #75091) - Simplify implementation of various pointer methods r? ```@scottmcm``` ---- `from_raw_parts::<T>(this, metadata(self))` was annoying me for a while and I've finally figured out how it should _actually_ be done.
This commit is contained in:
commit
19efa2599c
@ -156,6 +156,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)]
|
||||
|
@ -79,19 +79,14 @@ pub const fn cast<U>(self) -> *const U {
|
||||
/// }
|
||||
/// ```
|
||||
#[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<U>(self, mut val: *const U) -> *const U
|
||||
pub const fn with_metadata_of<U>(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::<U>(self as *const (), metadata(meta))
|
||||
}
|
||||
|
||||
/// Changes constness without changing the type.
|
||||
@ -478,8 +473,7 @@ pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata)
|
||||
#[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::<u8>().offset(count).cast::<()>() };
|
||||
from_raw_parts::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -559,7 +553,7 @@ pub const fn wrapping_offset(self, count: isize) -> *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::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
|
||||
self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Masks out bits of the pointer according to a mask.
|
||||
@ -597,8 +591,7 @@ pub const fn wrapping_byte_offset(self, count: isize) -> Self {
|
||||
#[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::<T>(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 @@ pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
|
||||
#[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::<u8>().add(count).cast::<()>() };
|
||||
from_raw_parts::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer (convenience for
|
||||
@ -1026,8 +1018,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> Option<bool>
|
||||
#[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::<u8>().sub(count).cast::<()>() };
|
||||
from_raw_parts::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -1107,7 +1098,7 @@ pub const fn wrapping_add(self, count: usize) -> Self
|
||||
#[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::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
|
||||
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -1187,7 +1178,7 @@ pub const fn wrapping_sub(self, count: usize) -> Self
|
||||
#[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::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
|
||||
self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Reads the value from `self` without moving it. This leaves the
|
||||
|
@ -78,23 +78,14 @@ pub const fn cast<U>(self) -> *mut U {
|
||||
/// }
|
||||
/// ```
|
||||
#[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<U>(self, val: *const U) -> *mut U
|
||||
pub const fn with_metadata_of<U>(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::<U>(self as *mut (), metadata(meta))
|
||||
}
|
||||
|
||||
/// Changes constness without changing the type.
|
||||
@ -496,8 +487,7 @@ pub const fn to_raw_parts(self) -> (*mut (), <T as super::Pointee>::Metadata) {
|
||||
#[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::<u8>().offset(count).cast::<()>() };
|
||||
from_raw_parts_mut::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -576,10 +566,7 @@ pub const fn wrapping_offset(self, count: isize) -> *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::<T>(
|
||||
self.cast::<u8>().wrapping_offset(count).cast::<()>(),
|
||||
metadata(self),
|
||||
)
|
||||
self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Masks out bits of the pointer according to a mask.
|
||||
@ -620,8 +607,7 @@ pub const fn wrapping_byte_offset(self, count: isize) -> Self {
|
||||
#[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::<T>(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 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
#[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::<u8>().add(count).cast::<()>() };
|
||||
from_raw_parts_mut::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer (convenience for
|
||||
@ -1135,8 +1120,7 @@ pub const fn guaranteed_ne(self, other: *mut T) -> Option<bool>
|
||||
#[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::<u8>().sub(count).cast::<()>() };
|
||||
from_raw_parts_mut::<T>(this, metadata(self))
|
||||
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -1216,7 +1200,7 @@ pub const fn wrapping_add(self, count: usize) -> Self
|
||||
#[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::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
|
||||
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||
@ -1296,7 +1280,7 @@ pub const fn wrapping_sub(self, count: usize) -> Self
|
||||
#[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::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
|
||||
self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
|
||||
}
|
||||
|
||||
/// Reads the value from `self` without moving it. This leaves the
|
||||
|
Loading…
Reference in New Issue
Block a user