diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-04-04 15:11:16 +0400 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-05-12 12:54:21 +0400 |
| commit | a908eec4389137bcaefb2bad6eb1efb34cb1be2d (patch) | |
| tree | 4b289c06aad1af59371a2f73acbe7c650762d189 | |
| parent | c8c91f757ab82b4ccb5bed42927163cca6fbf90a (diff) | |
| download | rust-a908eec4389137bcaefb2bad6eb1efb34cb1be2d.tar.gz rust-a908eec4389137bcaefb2bad6eb1efb34cb1be2d.zip | |
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`.
| -rw-r--r-- | library/core/src/ptr/const_ptr.rs | 82 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 85 |
2 files changed, 89 insertions, 78 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8e127c350cc..0d936eacc51 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -462,16 +462,17 @@ impl<T: ?Sized> *const T { /// This is purely a convenience for casting to a `u8` pointer and /// using [offset][pointer::offset] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_offset(self, count: isize) -> Self { // 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. @@ -543,15 +544,15 @@ impl<T: ?Sized> *const T { /// This is purely a convenience for casting to a `u8` pointer and /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method /// for documentation. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_offset(count).cast::<T>() + pub const fn wrapping_byte_offset(self, count: isize) -> Self { + from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self)) } /// 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 /// using [offset_from][pointer::offset_from] on it. See that method for /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize { // SAFETY: the caller must uphold the safety contract for `offset_from`. 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 /// using [add][pointer::add] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_add(self, count: usize) -> Self { // 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 @@ -958,16 +960,17 @@ impl<T: ?Sized> *const T { /// This is purely a convenience for casting to a `u8` pointer and /// using [sub][pointer::sub] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_sub(self, count: usize) -> Self { // 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. @@ -1039,15 +1042,15 @@ impl<T: ?Sized> *const T { /// /// 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. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_add(count).cast::<T>() + pub const fn wrapping_byte_add(self, count: usize) -> Self { + from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self)) } /// 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 /// 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] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_sub(count).cast::<T>() + pub const fn wrapping_byte_sub(self, count: usize) -> Self { + from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self)) } /// 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`. /// + /// For non-`Sized` pointees this operation considers only the data pointer, + /// ignoring the metadata. + /// /// # Panics /// /// The function panics if `align` is not a power-of-two (this includes 0). #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "none")] - pub fn is_aligned_to(self, align: usize) -> bool - where - T: Sized, - { + pub fn is_aligned_to(self, align: usize) -> bool { if !align.is_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 } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 20a757101e4..d223d76ac3a 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -474,16 +474,17 @@ impl<T: ?Sized> *mut T { /// This is purely a convenience for casting to a `u8` pointer and /// using [offset][pointer::offset] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_offset(self, count: isize) -> Self { // 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. @@ -554,15 +555,18 @@ impl<T: ?Sized> *mut T { /// This is purely a convenience for casting to a `u8` pointer and /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method /// for documentation. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_offset(count).cast::<T>() + pub const fn wrapping_byte_offset(self, count: isize) -> Self { + from_raw_parts_mut::<T>( + self.cast::<u8>().wrapping_offset(count).cast::<()>(), + metadata(self), + ) } /// 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 /// using [offset_from][pointer::offset_from] on it. See that method for /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize { // SAFETY: the caller must uphold the safety contract for `offset_from`. 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 /// using [add][pointer::add] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_add(self, count: usize) -> Self { // 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 @@ -1067,16 +1072,17 @@ impl<T: ?Sized> *mut T { /// This is purely a convenience for casting to a `u8` pointer and /// using [sub][pointer::sub] on it. See that method for documentation /// and safety requirements. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { + pub const unsafe fn byte_sub(self, count: usize) -> Self { // 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. @@ -1148,15 +1154,15 @@ impl<T: ?Sized> *mut T { /// /// 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. + /// + /// For non-`Sized` pointees this operation changes only the data pointer, + /// leaving the metadata untouched. #[must_use] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_add(count).cast::<T>() + pub const fn wrapping_byte_add(self, count: usize) -> Self { + from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self)) } /// 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 /// 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] #[inline(always)] #[unstable(feature = "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 - where - T: Sized, - { - self.cast::<u8>().wrapping_sub(count).cast::<T>() + pub const fn wrapping_byte_sub(self, count: usize) -> Self { + from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self)) } /// 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`. /// + /// For non-`Sized` pointees this operation considers only the data pointer, + /// ignoring the metadata. + /// /// # Panics /// /// The function panics if `align` is not a power-of-two (this includes 0). #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "none")] - pub fn is_aligned_to(self, align: usize) -> bool - where - T: Sized, - { + pub fn is_aligned_to(self, align: usize) -> bool { if !align.is_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 } } |
