Skip to content

Commit b04b762

Browse files
authored
Rollup merge of rust-lang#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 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.
2 parents c95fe41 + d3b5192 commit b04b762

File tree

3 files changed

+21
-45
lines changed

3 files changed

+21
-45
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
#![feature(maybe_uninit_uninit_array)]
161161
#![feature(ptr_alignment_type)]
162162
#![feature(ptr_metadata)]
163+
#![feature(set_ptr_value)]
163164
#![feature(slice_ptr_get)]
164165
#![feature(slice_split_at_unchecked)]
165166
#![feature(str_internals)]

library/core/src/ptr/const_ptr.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,14 @@ impl<T: ?Sized> *const T {
7979
/// }
8080
/// ```
8181
#[unstable(feature = "set_ptr_value", issue = "75091")]
82+
#[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
8283
#[must_use = "returns a new pointer rather than modifying its argument"]
8384
#[inline]
84-
pub fn with_metadata_of<U>(self, mut val: *const U) -> *const U
85+
pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
8586
where
8687
U: ?Sized,
8788
{
88-
let target = &mut val as *mut *const U as *mut *const u8;
89-
// SAFETY: In case of a thin pointer, this operations is identical
90-
// to a simple assignment. In case of a fat pointer, with the current
91-
// fat pointer layout implementation, the first field of such a
92-
// pointer is always the data pointer, which is likewise assigned.
93-
unsafe { *target = self as *const u8 };
94-
val
89+
from_raw_parts::<U>(self as *const (), metadata(meta))
9590
}
9691

9792
/// Changes constness without changing the type.
@@ -478,8 +473,7 @@ impl<T: ?Sized> *const T {
478473
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
479474
pub const unsafe fn byte_offset(self, count: isize) -> Self {
480475
// SAFETY: the caller must uphold the safety contract for `offset`.
481-
let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
482-
from_raw_parts::<T>(this, metadata(self))
476+
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
483477
}
484478

485479
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -559,7 +553,7 @@ impl<T: ?Sized> *const T {
559553
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
560554
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
561555
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
562-
from_raw_parts::<T>(self.cast::<u8>().wrapping_offset(count).cast::<()>(), metadata(self))
556+
self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
563557
}
564558

565559
/// Masks out bits of the pointer according to a mask.
@@ -597,8 +591,7 @@ impl<T: ?Sized> *const T {
597591
#[must_use = "returns a new pointer rather than modifying its argument"]
598592
#[inline(always)]
599593
pub fn mask(self, mask: usize) -> *const T {
600-
let this = intrinsics::ptr_mask(self.cast::<()>(), mask);
601-
from_raw_parts::<T>(this, metadata(self))
594+
intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
602595
}
603596

604597
/// Calculates the distance between two pointers. The returned value is in
@@ -939,8 +932,7 @@ impl<T: ?Sized> *const T {
939932
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
940933
pub const unsafe fn byte_add(self, count: usize) -> Self {
941934
// SAFETY: the caller must uphold the safety contract for `add`.
942-
let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
943-
from_raw_parts::<T>(this, metadata(self))
935+
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
944936
}
945937

946938
/// Calculates the offset from a pointer (convenience for
@@ -1026,8 +1018,7 @@ impl<T: ?Sized> *const T {
10261018
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
10271019
pub const unsafe fn byte_sub(self, count: usize) -> Self {
10281020
// SAFETY: the caller must uphold the safety contract for `sub`.
1029-
let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
1030-
from_raw_parts::<T>(this, metadata(self))
1021+
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
10311022
}
10321023

10331024
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1107,7 +1098,7 @@ impl<T: ?Sized> *const T {
11071098
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
11081099
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
11091100
pub const fn wrapping_byte_add(self, count: usize) -> Self {
1110-
from_raw_parts::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
1101+
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
11111102
}
11121103

11131104
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1187,7 +1178,7 @@ impl<T: ?Sized> *const T {
11871178
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
11881179
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
11891180
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
1190-
from_raw_parts::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
1181+
self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
11911182
}
11921183

11931184
/// Reads the value from `self` without moving it. This leaves the

library/core/src/ptr/mut_ptr.rs

+10-26
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,14 @@ impl<T: ?Sized> *mut T {
7878
/// }
7979
/// ```
8080
#[unstable(feature = "set_ptr_value", issue = "75091")]
81+
#[rustc_const_unstable(feature = "set_ptr_value", issue = "75091")]
8182
#[must_use = "returns a new pointer rather than modifying its argument"]
8283
#[inline]
83-
pub fn with_metadata_of<U>(self, val: *const U) -> *mut U
84+
pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U
8485
where
8586
U: ?Sized,
8687
{
87-
// Prepare in the type system that we will replace the pointer value with a mutable
88-
// pointer, taking the mutable provenance from the `self` pointer.
89-
let mut val = val as *mut U;
90-
// Pointer to the pointer value within the value.
91-
let target = &mut val as *mut *mut U as *mut *mut u8;
92-
// SAFETY: In case of a thin pointer, this operations is identical
93-
// to a simple assignment. In case of a fat pointer, with the current
94-
// fat pointer layout implementation, the first field of such a
95-
// pointer is always the data pointer, which is likewise assigned.
96-
unsafe { *target = self as *mut u8 };
97-
val
88+
from_raw_parts_mut::<U>(self as *mut (), metadata(meta))
9889
}
9990

10091
/// Changes constness without changing the type.
@@ -496,8 +487,7 @@ impl<T: ?Sized> *mut T {
496487
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
497488
pub const unsafe fn byte_offset(self, count: isize) -> Self {
498489
// SAFETY: the caller must uphold the safety contract for `offset`.
499-
let this = unsafe { self.cast::<u8>().offset(count).cast::<()>() };
500-
from_raw_parts_mut::<T>(this, metadata(self))
490+
unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) }
501491
}
502492

503493
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -576,10 +566,7 @@ impl<T: ?Sized> *mut T {
576566
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
577567
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
578568
pub const fn wrapping_byte_offset(self, count: isize) -> Self {
579-
from_raw_parts_mut::<T>(
580-
self.cast::<u8>().wrapping_offset(count).cast::<()>(),
581-
metadata(self),
582-
)
569+
self.cast::<u8>().wrapping_offset(count).with_metadata_of(self)
583570
}
584571

585572
/// Masks out bits of the pointer according to a mask.
@@ -620,8 +607,7 @@ impl<T: ?Sized> *mut T {
620607
#[must_use = "returns a new pointer rather than modifying its argument"]
621608
#[inline(always)]
622609
pub fn mask(self, mask: usize) -> *mut T {
623-
let this = intrinsics::ptr_mask(self.cast::<()>(), mask) as *mut ();
624-
from_raw_parts_mut::<T>(this, metadata(self))
610+
intrinsics::ptr_mask(self.cast::<()>(), mask).cast_mut().with_metadata_of(self)
625611
}
626612

627613
/// Returns `None` if the pointer is null, or else returns a unique reference to
@@ -1048,8 +1034,7 @@ impl<T: ?Sized> *mut T {
10481034
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
10491035
pub const unsafe fn byte_add(self, count: usize) -> Self {
10501036
// SAFETY: the caller must uphold the safety contract for `add`.
1051-
let this = unsafe { self.cast::<u8>().add(count).cast::<()>() };
1052-
from_raw_parts_mut::<T>(this, metadata(self))
1037+
unsafe { self.cast::<u8>().add(count).with_metadata_of(self) }
10531038
}
10541039

10551040
/// Calculates the offset from a pointer (convenience for
@@ -1135,8 +1120,7 @@ impl<T: ?Sized> *mut T {
11351120
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
11361121
pub const unsafe fn byte_sub(self, count: usize) -> Self {
11371122
// SAFETY: the caller must uphold the safety contract for `sub`.
1138-
let this = unsafe { self.cast::<u8>().sub(count).cast::<()>() };
1139-
from_raw_parts_mut::<T>(this, metadata(self))
1123+
unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) }
11401124
}
11411125

11421126
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1216,7 +1200,7 @@ impl<T: ?Sized> *mut T {
12161200
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
12171201
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
12181202
pub const fn wrapping_byte_add(self, count: usize) -> Self {
1219-
from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_add(count).cast::<()>(), metadata(self))
1203+
self.cast::<u8>().wrapping_add(count).with_metadata_of(self)
12201204
}
12211205

12221206
/// Calculates the offset from a pointer using wrapping arithmetic.
@@ -1296,7 +1280,7 @@ impl<T: ?Sized> *mut T {
12961280
#[unstable(feature = "pointer_byte_offsets", issue = "96283")]
12971281
#[rustc_const_unstable(feature = "const_pointer_byte_offsets", issue = "96283")]
12981282
pub const fn wrapping_byte_sub(self, count: usize) -> Self {
1299-
from_raw_parts_mut::<T>(self.cast::<u8>().wrapping_sub(count).cast::<()>(), metadata(self))
1283+
self.cast::<u8>().wrapping_sub(count).with_metadata_of(self)
13001284
}
13011285

13021286
/// Reads the value from `self` without moving it. This leaves the

0 commit comments

Comments
 (0)