1
Fork 0

Lift the Sized requirement from convenience ptr fns

Since they work on byte pointers (by `.cast::<u8>()`ing them), there is
no need to know the size of `T` and so there is no need for `T: Sized`.

The `is_aligned_to` is similar, though it doesn't need the _alignment_
of `T`.
This commit is contained in:
Maybe Waffle 2022-04-04 15:11:16 +04:00
parent c8c91f757a
commit a908eec438
2 changed files with 89 additions and 78 deletions

View file

@ -462,16 +462,17 @@ impl<T: ?Sized> *const T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [offset][pointer::offset] on it. See that method for documentation /// using [offset][pointer::offset] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_offset(self, count: isize) -> Self pub const unsafe fn byte_offset(self, count: isize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `offset`. // SAFETY: the caller must uphold the safety contract for `offset`.
unsafe { self.cast::<u8>().offset(count).cast::<T>() } let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
from_raw_parts::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -543,15 +544,15 @@ impl<T: ?Sized> *const T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_offset][pointer::wrapping_offset] on it. See that method /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
/// for documentation. /// for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_offset(self, count: isize) -> Self pub const fn wrapping_byte_offset(self, count: isize) -> Self {
where from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
T: Sized,
{
self.cast::<u8>().wrapping_offset(count).cast::<T>()
} }
/// Calculates the distance between two pointers. The returned value is in /// Calculates the distance between two pointers. The returned value is in
@ -654,13 +655,13 @@ impl<T: ?Sized> *const T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [offset_from][pointer::offset_from] on it. See that method for /// using [offset_from][pointer::offset_from] on it. See that method for
/// documentation and safety requirements. /// documentation and safety requirements.
///
/// For non-`Sized` pointees this operation considers only the data pointers,
/// ignoring the metadata.
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `offset_from`. // SAFETY: the caller must uphold the safety contract for `offset_from`.
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
} }
@ -874,16 +875,17 @@ impl<T: ?Sized> *const T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [add][pointer::add] on it. See that method for documentation /// using [add][pointer::add] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_add(self, count: usize) -> Self pub const unsafe fn byte_add(self, count: usize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `add`. // SAFETY: the caller must uphold the safety contract for `add`.
unsafe { self.cast::<u8>().add(count).cast::<T>() } let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
from_raw_parts::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer (convenience for /// Calculates the offset from a pointer (convenience for
@ -958,16 +960,17 @@ impl<T: ?Sized> *const T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [sub][pointer::sub] on it. See that method for documentation /// using [sub][pointer::sub] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_sub(self, count: usize) -> Self pub const unsafe fn byte_sub(self, count: usize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `sub`. // SAFETY: the caller must uphold the safety contract for `sub`.
unsafe { self.cast::<u8>().sub(count).cast::<T>() } let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
from_raw_parts::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -1039,15 +1042,15 @@ impl<T: ?Sized> *const T {
/// ///
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation. /// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_add(self, count: usize) -> Self pub const fn wrapping_byte_add(self, count: usize) -> Self {
where from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
T: Sized,
{
self.cast::<u8>().wrapping_add(count).cast::<T>()
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -1119,15 +1122,15 @@ impl<T: ?Sized> *const T {
/// ///
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation. /// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_sub(self, count: usize) -> Self pub const fn wrapping_byte_sub(self, count: usize) -> Self {
where from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
T: Sized,
{
self.cast::<u8>().wrapping_sub(count).cast::<T>()
} }
/// Reads the value from `self` without moving it. This leaves the /// Reads the value from `self` without moving it. This leaves the
@ -1303,21 +1306,22 @@ impl<T: ?Sized> *const T {
/// Returns whether the pointer is aligned to `align`. /// Returns whether the pointer is aligned to `align`.
/// ///
/// For non-`Sized` pointees this operation considers only the data pointer,
/// ignoring the metadata.
///
/// # Panics /// # Panics
/// ///
/// The function panics if `align` is not a power-of-two (this includes 0). /// The function panics if `align` is not a power-of-two (this includes 0).
#[must_use] #[must_use]
#[inline] #[inline]
#[unstable(feature = "pointer_is_aligned", issue = "none")] #[unstable(feature = "pointer_is_aligned", issue = "none")]
pub fn is_aligned_to(self, align: usize) -> bool pub fn is_aligned_to(self, align: usize) -> bool {
where
T: Sized,
{
if !align.is_power_of_two() { if !align.is_power_of_two() {
panic!("is_aligned_to: align is not a power-of-two"); panic!("is_aligned_to: align is not a power-of-two");
} }
self.addr() % align == 0 // Cast is needed for `T: !Sized`
self.cast::<u8>().addr() % align == 0
} }
} }

View file

@ -474,16 +474,17 @@ impl<T: ?Sized> *mut T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [offset][pointer::offset] on it. See that method for documentation /// using [offset][pointer::offset] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_offset(self, count: isize) -> Self pub const unsafe fn byte_offset(self, count: isize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `offset`. // SAFETY: the caller must uphold the safety contract for `offset`.
unsafe { self.cast::<u8>().offset(count).cast::<T>() } let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
from_raw_parts_mut::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -554,15 +555,18 @@ impl<T: ?Sized> *mut T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_offset][pointer::wrapping_offset] on it. See that method /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
/// for documentation. /// for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_offset(self, count: isize) -> Self pub const fn wrapping_byte_offset(self, count: isize) -> Self {
where from_raw_parts_mut::<T>(
T: Sized, self.cast::<u8>().wrapping_offset(count).cast::<()>(),
{ metadata(self),
self.cast::<u8>().wrapping_offset(count).cast::<T>() )
} }
/// Returns `None` if the pointer is null, or else returns a unique reference to /// Returns `None` if the pointer is null, or else returns a unique reference to
@ -830,13 +834,13 @@ impl<T: ?Sized> *mut T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [offset_from][pointer::offset_from] on it. See that method for /// using [offset_from][pointer::offset_from] on it. See that method for
/// documentation and safety requirements. /// documentation and safety requirements.
///
/// For non-`Sized` pointees this operation considers only the data pointers,
/// ignoring the metadata.
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `offset_from`. // SAFETY: the caller must uphold the safety contract for `offset_from`.
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
} }
@ -983,16 +987,17 @@ impl<T: ?Sized> *mut T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [add][pointer::add] on it. See that method for documentation /// using [add][pointer::add] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_add(self, count: usize) -> Self pub const unsafe fn byte_add(self, count: usize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `add`. // SAFETY: the caller must uphold the safety contract for `add`.
unsafe { self.cast::<u8>().add(count).cast::<T>() } let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
from_raw_parts_mut::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer (convenience for /// Calculates the offset from a pointer (convenience for
@ -1067,16 +1072,17 @@ impl<T: ?Sized> *mut T {
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [sub][pointer::sub] on it. See that method for documentation /// using [sub][pointer::sub] on it. See that method for documentation
/// and safety requirements. /// and safety requirements.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const unsafe fn byte_sub(self, count: usize) -> Self pub const unsafe fn byte_sub(self, count: usize) -> Self {
where
T: Sized,
{
// SAFETY: the caller must uphold the safety contract for `sub`. // SAFETY: the caller must uphold the safety contract for `sub`.
unsafe { self.cast::<u8>().sub(count).cast::<T>() } let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
from_raw_parts_mut::<T>(this, metadata(self))
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -1148,15 +1154,15 @@ impl<T: ?Sized> *mut T {
/// ///
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation. /// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_add(self, count: usize) -> Self pub const fn wrapping_byte_add(self, count: usize) -> Self {
where from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
T: Sized,
{
self.cast::<u8>().wrapping_add(count).cast::<T>()
} }
/// Calculates the offset from a pointer using wrapping arithmetic. /// Calculates the offset from a pointer using wrapping arithmetic.
@ -1228,15 +1234,15 @@ impl<T: ?Sized> *mut T {
/// ///
/// This is purely a convenience for casting to a `u8` pointer and /// This is purely a convenience for casting to a `u8` pointer and
/// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation. /// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
///
/// For non-`Sized` pointees this operation changes only the data pointer,
/// leaving the metadata untouched.
#[must_use] #[must_use]
#[inline(always)] #[inline(always)]
#[unstable(feature = "pointer_byte_offsets", issue = "none")] #[unstable(feature = "pointer_byte_offsets", issue = "none")]
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")] #[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
pub const fn wrapping_byte_sub(self, count: usize) -> Self pub const fn wrapping_byte_sub(self, count: usize) -> Self {
where from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
T: Sized,
{
self.cast::<u8>().wrapping_sub(count).cast::<T>()
} }
/// Reads the value from `self` without moving it. This leaves the /// Reads the value from `self` without moving it. This leaves the
@ -1569,21 +1575,22 @@ impl<T: ?Sized> *mut T {
/// Returns whether the pointer is aligned to `align`. /// Returns whether the pointer is aligned to `align`.
/// ///
/// For non-`Sized` pointees this operation considers only the data pointer,
/// ignoring the metadata.
///
/// # Panics /// # Panics
/// ///
/// The function panics if `align` is not a power-of-two (this includes 0). /// The function panics if `align` is not a power-of-two (this includes 0).
#[must_use] #[must_use]
#[inline] #[inline]
#[unstable(feature = "pointer_is_aligned", issue = "none")] #[unstable(feature = "pointer_is_aligned", issue = "none")]
pub fn is_aligned_to(self, align: usize) -> bool pub fn is_aligned_to(self, align: usize) -> bool {
where
T: Sized,
{
if !align.is_power_of_two() { if !align.is_power_of_two() {
panic!("is_aligned_to: align is not a power-of-two"); panic!("is_aligned_to: align is not a power-of-two");
} }
self.addr() % align == 0 // Cast is needed for `T: !Sized`
self.cast::<u8>().addr() % align == 0
} }
} }