Skip to content

Commit d42d678

Browse files
committed
feat(byte_sub_ptr): add ptr::byte_sub_ptr
This is an API that naturally should exist as a combination of byte_offset_from and sub_ptr both existing (they showed up at similar times so this union was never made). Adding these is a logical (and perhaps final) precondition of stabilizing ptr_sub_ptr (rust-lang#95892).
1 parent 5119208 commit d42d678

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

library/core/src/ptr/const_ptr.rs

+19
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,25 @@ impl<T: ?Sized> *const T {
824824
unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
825825
}
826826

827+
/// Calculates the distance between two pointers, *where it's known that
828+
/// `self` is equal to or greater than `origin`*. The returned value is in
829+
/// units of **bytes**.
830+
///
831+
/// This is purely a convenience for casting to a `u8` pointer and
832+
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
833+
/// documentation and safety requirements.
834+
///
835+
/// For non-`Sized` pointees this operation considers only the data pointers,
836+
/// ignoring the metadata.
837+
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
838+
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
839+
#[inline]
840+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
841+
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize {
842+
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
843+
unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) }
844+
}
845+
827846
/// Returns whether two pointers are guaranteed to be equal.
828847
///
829848
/// At runtime this function behaves like `Some(self == other)`.

library/core/src/ptr/mut_ptr.rs

+19
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,25 @@ impl<T: ?Sized> *mut T {
984984
unsafe { (self as *const T).sub_ptr(origin) }
985985
}
986986

987+
/// Calculates the distance between two pointers, *where it's known that
988+
/// `self` is equal to or greater than `origin`*. The returned value is in
989+
/// units of **bytes**.
990+
///
991+
/// This is purely a convenience for casting to a `u8` pointer and
992+
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
993+
/// documentation and safety requirements.
994+
///
995+
/// For non-`Sized` pointees this operation considers only the data pointers,
996+
/// ignoring the metadata.
997+
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
998+
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
999+
#[inline]
1000+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1001+
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize {
1002+
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
1003+
unsafe { (self as *const T).byte_sub_ptr(origin) }
1004+
}
1005+
9871006
/// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
9881007
///
9891008
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer

library/core/src/ptr/non_null.rs

+19
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,25 @@ impl<T: ?Sized> NonNull<T> {
957957
unsafe { self.pointer.sub_ptr(subtracted.pointer) }
958958
}
959959

960+
/// Calculates the distance between two pointers, *where it's known that
961+
/// `self` is equal to or greater than `origin`*. The returned value is in
962+
/// units of **bytes**.
963+
///
964+
/// This is purely a convenience for casting to a `u8` pointer and
965+
/// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for
966+
/// documentation and safety requirements.
967+
///
968+
/// For non-`Sized` pointees this operation considers only the data pointers,
969+
/// ignoring the metadata.
970+
#[unstable(feature = "non_null_convenience", issue = "117691")]
971+
#[rustc_const_unstable(feature = "non_null_convenience", issue = "117691")]
972+
#[inline(always)]
973+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
974+
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
975+
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
976+
unsafe { self.pointer.byte_sub_ptr(origin.pointer) }
977+
}
978+
960979
/// Reads the value from `self` without moving it. This leaves the
961980
/// memory in `self` unchanged.
962981
///

0 commit comments

Comments
 (0)