@@ -390,37 +390,26 @@ impl<T: ?Sized> *const T {
390390 if self . is_null ( ) { None } else { Some ( unsafe { & * ( self as * const MaybeUninit < T > ) } ) }
391391 }
392392
393- /// Calculates the offset from a pointer.
393+ /// Adds an offset to a pointer.
394394 ///
395395 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
396396 /// offset of `3 * size_of::<T>()` bytes.
397397 ///
398398 /// # Safety
399399 ///
400- /// If any of the following conditions are violated, the result is Undefined
401- /// Behavior:
402- ///
403- /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
404- /// pointer must be either in bounds or at the end of the same [allocated object].
405- /// (If it is zero, then the function is always well-defined.)
400+ /// If any of the following conditions are violated, the result is Undefined Behavior:
406401 ///
407- /// * The computed offset, **in bytes**, cannot overflow an `isize`.
402+ /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
408403 ///
409- /// * The offset being in bounds cannot rely on "wrapping around" the address
410- /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
404+ /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
405+ /// [allocated object], and the entire memory range between `self` and the result must be in
406+ /// bounds of that allocated object. In particular, this range must not "wrap around" the egde
407+ /// of the address space.
411408 ///
412- /// The compiler and standard library generally tries to ensure allocations
413- /// never reach a size where an offset is a concern. For instance, `Vec`
414- /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
415- /// `vec.as_ptr().add(vec.len())` is always safe.
416- ///
417- /// Most platforms fundamentally can't even construct such an allocation.
418- /// For instance, no known 64-bit platform can ever serve a request
419- /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
420- /// However, some 32-bit and 16-bit platforms may successfully serve a request for
421- /// more than `isize::MAX` bytes with things like Physical Address
422- /// Extension. As such, memory acquired directly from allocators or memory
423- /// mapped files *may* be too large to handle with this function.
409+ /// Allocated objects can never be larger than `isize::MAX`, so if the computed offset stays in
410+ /// bounds of the allocated object, it is guaranteed to satisfy the first requirement. This
411+ /// implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
412+ /// safe.
424413 ///
425414 /// Consider using [`wrapping_offset`] instead if these constraints are
426415 /// difficult to satisfy. The only advantage of this method is that it
@@ -623,7 +612,7 @@ impl<T: ?Sized> *const T {
623612 /// * The distance between the pointers, in bytes, must be an exact multiple
624613 /// of the size of `T`.
625614 ///
626- /// As a consequence, the absolute distance between the pointers, ** in bytes** , computed on
615+ /// As a consequence, the absolute distance between the pointers, in bytes, computed on
627616 /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is
628617 /// implied by the in-bounds requirement, and the fact that no allocated object can be larger
629618 /// than `isize::MAX`.
@@ -863,37 +852,26 @@ impl<T: ?Sized> *const T {
863852 }
864853 }
865854
866- /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
855+ /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
867856 ///
868857 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
869858 /// offset of `3 * size_of::<T>()` bytes.
870859 ///
871860 /// # Safety
872861 ///
873- /// If any of the following conditions are violated, the result is Undefined
874- /// Behavior:
875- ///
876- /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
877- /// pointer must be either in bounds or at the end of the same [allocated object].
878- /// (If it is zero, then the function is always well-defined.)
879- ///
880- /// * The computed offset, **in bytes**, cannot overflow an `isize`.
862+ /// If any of the following conditions are violated, the result is Undefined Behavior:
881863 ///
882- /// * The offset being in bounds cannot rely on "wrapping around" the address
883- /// space. That is, the infinite-precision sum must fit in a `usize`.
864+ /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
884865 ///
885- /// The compiler and standard library generally tries to ensure allocations
886- /// never reach a size where an offset is a concern. For instance, `Vec`
887- /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
888- /// `vec.as_ptr().add(vec.len())` is always safe .
866+ /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
867+ /// [allocated object], and the entire memory range between `self` and the result must be in
868+ /// bounds of that allocated object. In particular, this range must not "wrap around" the egde
869+ /// of the address space .
889870 ///
890- /// Most platforms fundamentally can't even construct such an allocation.
891- /// For instance, no known 64-bit platform can ever serve a request
892- /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
893- /// However, some 32-bit and 16-bit platforms may successfully serve a request for
894- /// more than `isize::MAX` bytes with things like Physical Address
895- /// Extension. As such, memory acquired directly from allocators or memory
896- /// mapped files *may* be too large to handle with this function.
871+ /// Allocated objects can never be larger than `isize::MAX`, so if the computed offset stays in
872+ /// bounds of the allocated object, it is guaranteed to satisfy the first requirement. This
873+ /// implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
874+ /// safe.
897875 ///
898876 /// Consider using [`wrapping_add`] instead if these constraints are
899877 /// difficult to satisfy. The only advantage of this method is that it
@@ -947,38 +925,27 @@ impl<T: ?Sized> *const T {
947925 unsafe { self . cast :: < u8 > ( ) . add ( count) . with_metadata_of ( self ) }
948926 }
949927
950- /// Calculates the offset from a pointer (convenience for
928+ /// Subtracts an offset from a pointer (convenience for
951929 /// `.offset((count as isize).wrapping_neg())`).
952930 ///
953931 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
954932 /// offset of `3 * size_of::<T>()` bytes.
955933 ///
956934 /// # Safety
957935 ///
958- /// If any of the following conditions are violated, the result is Undefined
959- /// Behavior:
960- ///
961- /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting
962- /// pointer must be either in bounds or at the end of the same [allocated object].
963- /// (If it is zero, then the function is always well-defined.)
964- ///
965- /// * The computed offset cannot exceed `isize::MAX` **bytes**.
936+ /// If any of the following conditions are violated, the result is Undefined Behavior:
966937 ///
967- /// * The offset being in bounds cannot rely on "wrapping around" the address
968- /// space. That is, the infinite-precision sum must fit in a usize.
938+ /// * The computed offset, `count * size_of::<T>()` bytes, must not overflow `isize`.
969939 ///
970- /// The compiler and standard library generally tries to ensure allocations
971- /// never reach a size where an offset is a concern. For instance, `Vec`
972- /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
973- /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe .
940+ /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
941+ /// [allocated object], and the entire memory range between `self` and the result must be in
942+ /// bounds of that allocated object. In particular, this range must not "wrap around" the egde
943+ /// of the address space .
974944 ///
975- /// Most platforms fundamentally can't even construct such an allocation.
976- /// For instance, no known 64-bit platform can ever serve a request
977- /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
978- /// However, some 32-bit and 16-bit platforms may successfully serve a request for
979- /// more than `isize::MAX` bytes with things like Physical Address
980- /// Extension. As such, memory acquired directly from allocators or memory
981- /// mapped files *may* be too large to handle with this function.
945+ /// Allocated objects can never be larger than `isize::MAX`, so if the computed offset stays in
946+ /// bounds of the allocated object, it is guaranteed to satisfy the first requirement. This
947+ /// implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
948+ /// safe.
982949 ///
983950 /// Consider using [`wrapping_sub`] instead if these constraints are
984951 /// difficult to satisfy. The only advantage of this method is that it
0 commit comments