Skip to content

Commit

Permalink
Rollup merge of rust-lang#103701 - WaffleLapkin:__points-at-implement…
Browse files Browse the repository at this point in the history
…ation__--this-can-be-simplified, r=scottmcm

Simplify some pointer method implementations

- Make `pointer::with_metadata_of` const (+simplify implementation) (cc rust-lang#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.
  • Loading branch information
Manishearth authored Nov 18, 2022
2 parents c95fe41 + d3b5192 commit b04b762
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 45 deletions.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
29 changes: 10 additions & 19 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,14 @@ impl<T: ?Sized> *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<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.
Expand Down Expand Up @@ -478,8 +473,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -559,7 +553,7 @@ impl<T: ?Sized> *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.
Expand Down Expand Up @@ -597,8 +591,7 @@ impl<T: ?Sized> *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::<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
Expand Down Expand Up @@ -939,8 +932,7 @@ impl<T: ?Sized> *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::<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
Expand Down Expand Up @@ -1026,8 +1018,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -1107,7 +1098,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -1187,7 +1178,7 @@ impl<T: ?Sized> *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::<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
Expand Down
36 changes: 10 additions & 26 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,14 @@ impl<T: ?Sized> *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<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.
Expand Down Expand Up @@ -496,8 +487,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -576,10 +566,7 @@ impl<T: ?Sized> *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.
Expand Down Expand Up @@ -620,8 +607,7 @@ impl<T: ?Sized> *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::<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
Expand Down Expand Up @@ -1048,8 +1034,7 @@ impl<T: ?Sized> *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::<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
Expand Down Expand Up @@ -1135,8 +1120,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -1216,7 +1200,7 @@ impl<T: ?Sized> *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::<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.
Expand Down Expand Up @@ -1296,7 +1280,7 @@ impl<T: ?Sized> *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::<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
Expand Down

0 comments on commit b04b762

Please sign in to comment.