Skip to content

Commit a908eec

Browse files
committed
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`.
1 parent c8c91f7 commit a908eec

File tree

2 files changed

+89
-78
lines changed

2 files changed

+89
-78
lines changed

library/core/src/ptr/const_ptr.rs

+43-39
Original file line numberDiff line numberDiff line change
@@ -462,16 +462,17 @@ impl<T: ?Sized> *const T {
462462
/// This is purely a convenience for casting to a `u8` pointer and
463463
/// using [offset][pointer::offset] on it. See that method for documentation
464464
/// and safety requirements.
465+
///
466+
/// For non-`Sized` pointees this operation changes only the data pointer,
467+
/// leaving the metadata untouched.
465468
#[must_use]
466469
#[inline(always)]
467470
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
468471
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
469-
pub const unsafe fn byte_offset(self, count: isize) -> Self
470-
where
471-
T: Sized,
472-
{
472+
pub const unsafe fn byte_offset(self, count: isize) -> Self {
473473
// SAFETY: the caller must uphold the safety contract for `offset`.
474-
unsafe { self.cast::<u8>().offset(count).cast::<T>() }
474+
let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
475+
from_raw_parts::<T>(this, metadata(self))
475476
}
476477

477478
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -543,15 +544,15 @@ impl<T: ?Sized> *const T {
543544
/// This is purely a convenience for casting to a `u8` pointer and
544545
/// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
545546
/// for documentation.
547+
///
548+
/// For non-`Sized` pointees this operation changes only the data pointer,
549+
/// leaving the metadata untouched.
546550
#[must_use]
547551
#[inline(always)]
548552
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
549553
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
550-
pub const fn wrapping_byte_offset(self, count: isize) -> Self
551-
where
552-
T: Sized,
553-
{
554-
self.cast::<u8>().wrapping_offset(count).cast::<T>()
554+
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
555+
from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
555556
}
556557

557558
/// Calculates the distance between two pointers. The returned value is in
@@ -654,13 +655,13 @@ impl<T: ?Sized> *const T {
654655
/// This is purely a convenience for casting to a `u8` pointer and
655656
/// using [offset_from][pointer::offset_from] on it. See that method for
656657
/// documentation and safety requirements.
658+
///
659+
/// For non-`Sized` pointees this operation considers only the data pointers,
660+
/// ignoring the metadata.
657661
#[inline(always)]
658662
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
659663
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
660-
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize
661-
where
662-
T: Sized,
663-
{
664+
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize {
664665
// SAFETY: the caller must uphold the safety contract for `offset_from`.
665666
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
666667
}
@@ -874,16 +875,17 @@ impl<T: ?Sized> *const T {
874875
/// This is purely a convenience for casting to a `u8` pointer and
875876
/// using [add][pointer::add] on it. See that method for documentation
876877
/// and safety requirements.
878+
///
879+
/// For non-`Sized` pointees this operation changes only the data pointer,
880+
/// leaving the metadata untouched.
877881
#[must_use]
878882
#[inline(always)]
879883
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
880884
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
881-
pub const unsafe fn byte_add(self, count: usize) -> Self
882-
where
883-
T: Sized,
884-
{
885+
pub const unsafe fn byte_add(self, count: usize) -> Self {
885886
// SAFETY: the caller must uphold the safety contract for `add`.
886-
unsafe { self.cast::<u8>().add(count).cast::<T>() }
887+
let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
888+
from_raw_parts::<T>(this, metadata(self))
887889
}
888890

889891
/// Calculates the offset from a pointer (convenience for
@@ -958,16 +960,17 @@ impl<T: ?Sized> *const T {
958960
/// This is purely a convenience for casting to a `u8` pointer and
959961
/// using [sub][pointer::sub] on it. See that method for documentation
960962
/// and safety requirements.
963+
///
964+
/// For non-`Sized` pointees this operation changes only the data pointer,
965+
/// leaving the metadata untouched.
961966
#[must_use]
962967
#[inline(always)]
963968
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
964969
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
965-
pub const unsafe fn byte_sub(self, count: usize) -> Self
966-
where
967-
T: Sized,
968-
{
970+
pub const unsafe fn byte_sub(self, count: usize) -> Self {
969971
// SAFETY: the caller must uphold the safety contract for `sub`.
970-
unsafe { self.cast::<u8>().sub(count).cast::<T>() }
972+
let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
973+
from_raw_parts::<T>(this, metadata(self))
971974
}
972975

973976
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1039,15 +1042,15 @@ impl<T: ?Sized> *const T {
10391042
///
10401043
/// This is purely a convenience for casting to a `u8` pointer and
10411044
/// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
1045+
///
1046+
/// For non-`Sized` pointees this operation changes only the data pointer,
1047+
/// leaving the metadata untouched.
10421048
#[must_use]
10431049
#[inline(always)]
10441050
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
10451051
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
1046-
pub const fn wrapping_byte_add(self, count: usize) -> Self
1047-
where
1048-
T: Sized,
1049-
{
1050-
self.cast::<u8>().wrapping_add(count).cast::<T>()
1052+
pub const fn wrapping_byte_add(self, count: usize) -> Self {
1053+
from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
10511054
}
10521055

10531056
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1119,15 +1122,15 @@ impl<T: ?Sized> *const T {
11191122
///
11201123
/// This is purely a convenience for casting to a `u8` pointer and
11211124
/// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
1125+
///
1126+
/// For non-`Sized` pointees this operation changes only the data pointer,
1127+
/// leaving the metadata untouched.
11221128
#[must_use]
11231129
#[inline(always)]
11241130
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
11251131
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
1126-
pub const fn wrapping_byte_sub(self, count: usize) -> Self
1127-
where
1128-
T: Sized,
1129-
{
1130-
self.cast::<u8>().wrapping_sub(count).cast::<T>()
1132+
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
1133+
from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
11311134
}
11321135

11331136
/// Reads the value from `self` without moving it. This leaves the
@@ -1303,21 +1306,22 @@ impl<T: ?Sized> *const T {
13031306

13041307
/// Returns whether the pointer is aligned to `align`.
13051308
///
1309+
/// For non-`Sized` pointees this operation considers only the data pointer,
1310+
/// ignoring the metadata.
1311+
///
13061312
/// # Panics
13071313
///
13081314
/// The function panics if `align` is not a power-of-two (this includes 0).
13091315
#[must_use]
13101316
#[inline]
13111317
#[unstable(feature = "pointer_is_aligned", issue = "none")]
1312-
pub fn is_aligned_to(self, align: usize) -> bool
1313-
where
1314-
T: Sized,
1315-
{
1318+
pub fn is_aligned_to(self, align: usize) -> bool {
13161319
if !align.is_power_of_two() {
13171320
panic!("is_aligned_to: align is not a power-of-two");
13181321
}
13191322

1320-
self.addr() % align == 0
1323+
// Cast is needed for `T: !Sized`
1324+
self.cast::<u8>().addr() % align == 0
13211325
}
13221326
}
13231327

library/core/src/ptr/mut_ptr.rs

+46-39
Original file line numberDiff line numberDiff line change
@@ -474,16 +474,17 @@ impl<T: ?Sized> *mut T {
474474
/// This is purely a convenience for casting to a `u8` pointer and
475475
/// using [offset][pointer::offset] on it. See that method for documentation
476476
/// and safety requirements.
477+
///
478+
/// For non-`Sized` pointees this operation changes only the data pointer,
479+
/// leaving the metadata untouched.
477480
#[must_use]
478481
#[inline(always)]
479482
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
480483
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
481-
pub const unsafe fn byte_offset(self, count: isize) -> Self
482-
where
483-
T: Sized,
484-
{
484+
pub const unsafe fn byte_offset(self, count: isize) -> Self {
485485
// SAFETY: the caller must uphold the safety contract for `offset`.
486-
unsafe { self.cast::<u8>().offset(count).cast::<T>() }
486+
let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
487+
from_raw_parts_mut::<T>(this, metadata(self))
487488
}
488489

489490
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -554,15 +555,18 @@ impl<T: ?Sized> *mut T {
554555
/// This is purely a convenience for casting to a `u8` pointer and
555556
/// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
556557
/// for documentation.
558+
///
559+
/// For non-`Sized` pointees this operation changes only the data pointer,
560+
/// leaving the metadata untouched.
557561
#[must_use]
558562
#[inline(always)]
559563
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
560564
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
561-
pub const fn wrapping_byte_offset(self, count: isize) -> Self
562-
where
563-
T: Sized,
564-
{
565-
self.cast::<u8>().wrapping_offset(count).cast::<T>()
565+
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
566+
from_raw_parts_mut::<T>(
567+
self.cast::<u8>().wrapping_offset(count).cast::<()>(),
568+
metadata(self),
569+
)
566570
}
567571

568572
/// Returns `None` if the pointer is null, or else returns a unique reference to
@@ -830,13 +834,13 @@ impl<T: ?Sized> *mut T {
830834
/// This is purely a convenience for casting to a `u8` pointer and
831835
/// using [offset_from][pointer::offset_from] on it. See that method for
832836
/// documentation and safety requirements.
837+
///
838+
/// For non-`Sized` pointees this operation considers only the data pointers,
839+
/// ignoring the metadata.
833840
#[inline(always)]
834841
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
835842
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
836-
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize
837-
where
838-
T: Sized,
839-
{
843+
pub const unsafe fn byte_offset_from(self, origin: *const T) -> isize {
840844
// SAFETY: the caller must uphold the safety contract for `offset_from`.
841845
unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
842846
}
@@ -983,16 +987,17 @@ impl<T: ?Sized> *mut T {
983987
/// This is purely a convenience for casting to a `u8` pointer and
984988
/// using [add][pointer::add] on it. See that method for documentation
985989
/// and safety requirements.
990+
///
991+
/// For non-`Sized` pointees this operation changes only the data pointer,
992+
/// leaving the metadata untouched.
986993
#[must_use]
987994
#[inline(always)]
988995
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
989996
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
990-
pub const unsafe fn byte_add(self, count: usize) -> Self
991-
where
992-
T: Sized,
993-
{
997+
pub const unsafe fn byte_add(self, count: usize) -> Self {
994998
// SAFETY: the caller must uphold the safety contract for `add`.
995-
unsafe { self.cast::<u8>().add(count).cast::<T>() }
999+
let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
1000+
from_raw_parts_mut::<T>(this, metadata(self))
9961001
}
9971002

9981003
/// Calculates the offset from a pointer (convenience for
@@ -1067,16 +1072,17 @@ impl<T: ?Sized> *mut T {
10671072
/// This is purely a convenience for casting to a `u8` pointer and
10681073
/// using [sub][pointer::sub] on it. See that method for documentation
10691074
/// and safety requirements.
1075+
///
1076+
/// For non-`Sized` pointees this operation changes only the data pointer,
1077+
/// leaving the metadata untouched.
10701078
#[must_use]
10711079
#[inline(always)]
10721080
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
10731081
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
1074-
pub const unsafe fn byte_sub(self, count: usize) -> Self
1075-
where
1076-
T: Sized,
1077-
{
1082+
pub const unsafe fn byte_sub(self, count: usize) -> Self {
10781083
// SAFETY: the caller must uphold the safety contract for `sub`.
1079-
unsafe { self.cast::<u8>().sub(count).cast::<T>() }
1084+
let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
1085+
from_raw_parts_mut::<T>(this, metadata(self))
10801086
}
10811087

10821088
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1148,15 +1154,15 @@ impl<T: ?Sized> *mut T {
11481154
///
11491155
/// This is purely a convenience for casting to a `u8` pointer and
11501156
/// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
1157+
///
1158+
/// For non-`Sized` pointees this operation changes only the data pointer,
1159+
/// leaving the metadata untouched.
11511160
#[must_use]
11521161
#[inline(always)]
11531162
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
11541163
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
1155-
pub const fn wrapping_byte_add(self, count: usize) -> Self
1156-
where
1157-
T: Sized,
1158-
{
1159-
self.cast::<u8>().wrapping_add(count).cast::<T>()
1164+
pub const fn wrapping_byte_add(self, count: usize) -> Self {
1165+
from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
11601166
}
11611167

11621168
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1228,15 +1234,15 @@ impl<T: ?Sized> *mut T {
12281234
///
12291235
/// This is purely a convenience for casting to a `u8` pointer and
12301236
/// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
1237+
///
1238+
/// For non-`Sized` pointees this operation changes only the data pointer,
1239+
/// leaving the metadata untouched.
12311240
#[must_use]
12321241
#[inline(always)]
12331242
#[unstable(feature = "pointer_byte_offsets", issue = "none")]
12341243
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "none")]
1235-
pub const fn wrapping_byte_sub(self, count: usize) -> Self
1236-
where
1237-
T: Sized,
1238-
{
1239-
self.cast::<u8>().wrapping_sub(count).cast::<T>()
1244+
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
1245+
from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
12401246
}
12411247

12421248
/// Reads the value from `self` without moving it. This leaves the
@@ -1569,21 +1575,22 @@ impl<T: ?Sized> *mut T {
15691575

15701576
/// Returns whether the pointer is aligned to `align`.
15711577
///
1578+
/// For non-`Sized` pointees this operation considers only the data pointer,
1579+
/// ignoring the metadata.
1580+
///
15721581
/// # Panics
15731582
///
15741583
/// The function panics if `align` is not a power-of-two (this includes 0).
15751584
#[must_use]
15761585
#[inline]
15771586
#[unstable(feature = "pointer_is_aligned", issue = "none")]
1578-
pub fn is_aligned_to(self, align: usize) -> bool
1579-
where
1580-
T: Sized,
1581-
{
1587+
pub fn is_aligned_to(self, align: usize) -> bool {
15821588
if !align.is_power_of_two() {
15831589
panic!("is_aligned_to: align is not a power-of-two");
15841590
}
15851591

1586-
self.addr() % align == 0
1592+
// Cast is needed for `T: !Sized`
1593+
self.cast::<u8>().addr() % align == 0
15871594
}
15881595
}
15891596

0 commit comments

Comments
 (0)