Skip to content

Commit 9d03362

Browse files
committed
Auto merge of rust-lang#121919 - Gankra:ptr_sub, r=scottmcm
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).
2 parents 5870f1c + d42d678 commit 9d03362

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
@@ -882,6 +882,25 @@ impl<T: ?Sized> *const T {
882882
unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
883883
}
884884

885+
/// Calculates the distance between two pointers, *where it's known that
886+
/// `self` is equal to or greater than `origin`*. The returned value is in
887+
/// units of **bytes**.
888+
///
889+
/// This is purely a convenience for casting to a `u8` pointer and
890+
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
891+
/// documentation and safety requirements.
892+
///
893+
/// For non-`Sized` pointees this operation considers only the data pointers,
894+
/// ignoring the metadata.
895+
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
896+
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
897+
#[inline]
898+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
899+
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize {
900+
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
901+
unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) }
902+
}
903+
885904
/// Returns whether two pointers are guaranteed to be equal.
886905
///
887906
/// 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
@@ -1086,6 +1086,25 @@ impl<T: ?Sized> *mut T {
10861086
unsafe { (self as *const T).sub_ptr(origin) }
10871087
}
10881088

1089+
/// Calculates the distance between two pointers, *where it's known that
1090+
/// `self` is equal to or greater than `origin`*. The returned value is in
1091+
/// units of **bytes**.
1092+
///
1093+
/// This is purely a convenience for casting to a `u8` pointer and
1094+
/// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
1095+
/// documentation and safety requirements.
1096+
///
1097+
/// For non-`Sized` pointees this operation considers only the data pointers,
1098+
/// ignoring the metadata.
1099+
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
1100+
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
1101+
#[inline]
1102+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1103+
pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize {
1104+
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
1105+
unsafe { (self as *const T).byte_sub_ptr(origin) }
1106+
}
1107+
10891108
/// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
10901109
///
10911110
/// `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
@@ -950,6 +950,25 @@ impl<T: ?Sized> NonNull<T> {
950950
unsafe { self.pointer.sub_ptr(subtracted.pointer) }
951951
}
952952

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

0 commit comments

Comments
 (0)