Skip to content

Commit a6dfd89

Browse files
committed
Auto merge of rust-lang#113797 - RalfJung:offset_from_docs, r=workingjubilee
offset_from: docs improvements This is the part of rust-lang#112837 that doesn't add a new function, just tweaks the existing docs.
2 parents c545019 + 9b7f9c4 commit a6dfd89

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

Diff for: library/core/src/ptr/const_ptr.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,16 @@ impl<T: ?Sized> *const T {
607607
/// Calculates the distance between two pointers. The returned value is in
608608
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
609609
///
610-
/// This function is the inverse of [`offset`].
610+
/// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
611+
/// except that it has a lot more opportunities for UB, in exchange for the compiler
612+
/// better understanding what you are doing.
613+
///
614+
/// The primary motivation of this method is for computing the `len` of an array/slice
615+
/// of `T` that you are currently representing as a "start" and "end" pointer
616+
/// (and "end" is "one past the end" of the array).
617+
/// In that case, `end.offset_from(start)` gets you the length of the array.
618+
///
619+
/// All of the following safety requirements are trivially satisfied for this usecase.
611620
///
612621
/// [`offset`]: #method.offset
613622
///
@@ -616,7 +625,7 @@ impl<T: ?Sized> *const T {
616625
/// If any of the following conditions are violated, the result is Undefined
617626
/// Behavior:
618627
///
619-
/// * Both the starting and other pointer must be either in bounds or one
628+
/// * Both `self` and `origin` must be either in bounds or one
620629
/// byte past the end of the same [allocated object].
621630
///
622631
/// * Both pointers must be *derived from* a pointer to the same object.
@@ -646,6 +655,14 @@ impl<T: ?Sized> *const T {
646655
/// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
647656
/// such large allocations either.)
648657
///
658+
/// The requirement for pointers to be derived from the same allocated object is primarily
659+
/// needed for `const`-compatibility: the distance between pointers into *different* allocated
660+
/// objects is not known at compile-time. However, the requirement also exists at
661+
/// runtime and may be exploited by optimizations. If you wish to compute the difference between
662+
/// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
663+
/// origin as isize) / mem::size_of::<T>()`.
664+
// FIXME: recommend `addr()` instead of `as usize` once that is stable.
665+
///
649666
/// [`add`]: #method.add
650667
/// [allocated object]: crate::ptr#allocated-object
651668
///
@@ -703,7 +720,7 @@ impl<T: ?Sized> *const T {
703720
/// units of **bytes**.
704721
///
705722
/// This is purely a convenience for casting to a `u8` pointer and
706-
/// using [offset_from][pointer::offset_from] on it. See that method for
723+
/// using [`offset_from`][pointer::offset_from] on it. See that method for
707724
/// documentation and safety requirements.
708725
///
709726
/// For non-`Sized` pointees this operation considers only the data pointers,

Diff for: library/core/src/ptr/mut_ptr.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,16 @@ impl<T: ?Sized> *mut T {
781781
/// Calculates the distance between two pointers. The returned value is in
782782
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
783783
///
784-
/// This function is the inverse of [`offset`].
784+
/// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
785+
/// except that it has a lot more opportunities for UB, in exchange for the compiler
786+
/// better understanding what you are doing.
787+
///
788+
/// The primary motivation of this method is for computing the `len` of an array/slice
789+
/// of `T` that you are currently representing as a "start" and "end" pointer
790+
/// (and "end" is "one past the end" of the array).
791+
/// In that case, `end.offset_from(start)` gets you the length of the array.
792+
///
793+
/// All of the following safety requirements are trivially satisfied for this usecase.
785794
///
786795
/// [`offset`]: pointer#method.offset-1
787796
///
@@ -790,7 +799,7 @@ impl<T: ?Sized> *mut T {
790799
/// If any of the following conditions are violated, the result is Undefined
791800
/// Behavior:
792801
///
793-
/// * Both the starting and other pointer must be either in bounds or one
802+
/// * Both `self` and `origin` must be either in bounds or one
794803
/// byte past the end of the same [allocated object].
795804
///
796805
/// * Both pointers must be *derived from* a pointer to the same object.
@@ -820,6 +829,14 @@ impl<T: ?Sized> *mut T {
820829
/// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
821830
/// such large allocations either.)
822831
///
832+
/// The requirement for pointers to be derived from the same allocated object is primarily
833+
/// needed for `const`-compatibility: the distance between pointers into *different* allocated
834+
/// objects is not known at compile-time. However, the requirement also exists at
835+
/// runtime and may be exploited by optimizations. If you wish to compute the difference between
836+
/// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
837+
/// origin as isize) / mem::size_of::<T>()`.
838+
// FIXME: recommend `addr()` instead of `as usize` once that is stable.
839+
///
823840
/// [`add`]: #method.add
824841
/// [allocated object]: crate::ptr#allocated-object
825842
///
@@ -875,7 +892,7 @@ impl<T: ?Sized> *mut T {
875892
/// units of **bytes**.
876893
///
877894
/// This is purely a convenience for casting to a `u8` pointer and
878-
/// using [offset_from][pointer::offset_from] on it. See that method for
895+
/// using [`offset_from`][pointer::offset_from] on it. See that method for
879896
/// documentation and safety requirements.
880897
///
881898
/// For non-`Sized` pointees this operation considers only the data pointers,

0 commit comments

Comments
 (0)