@@ -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