@@ -238,20 +238,21 @@ impl<T: ?Sized> *const T {
238238 /// It may *not* be used to access a different allocated object. Note that in Rust, every
239239 /// (stack-allocated) variable is considered a separate allocated object.
240240 ///
241- /// In other words, `let z = x.wrapping_add ((y as usize).wrapping_sub (x as usize) /
242- /// size_of::<T>())` does *not* make `z` the same as `y`: `z` is still attached to the object `x ` is
243- /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the
244- /// same allocated object.
241+ /// In other words, `let z = x.wrapping_offset ((y as isize) - (x as isize))` does *not* make `z`
242+ /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z ` is still
243+ /// attached to the object `x` is attached to , and dereferencing it is Undefined Behavior unless
244+ /// `x` and `y` point into the same allocated object.
245245 ///
246246 /// Compared to [`offset`], this method basically delays the requirement of staying within the
247247 /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object
248248 /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a
249249 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`]
250250 /// can be optimized better and is thus preferable in performance-sensitive code.
251251 ///
252- /// `x.wrapping_offset(o).wrapping_offset(-o)` is always the same as `x` (if `-o` does not
253- /// overflow). In other words, leaving the allocated object and then re-entering it later is
254- /// permitted.
252+ /// The delayed check only considers the value of the pointer that was dereferenced, not the
253+ /// intermediate values used during the computation of the final result. For example,
254+ /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other
255+ /// words, leaving the allocated object and then re-entering it later is permitted.
255256 ///
256257 /// If you need to cross object boundaries, cast the pointer to an integer and
257258 /// do the arithmetic there.
@@ -580,17 +581,19 @@ impl<T: ?Sized> *const T {
580581 /// It may *not* be used to access a different allocated object. Note that in Rust, every
581582 /// (stack-allocated) variable is considered a separate allocated object.
582583 ///
583- /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub (x as usize) /
584- /// size_of::<T>())` does *not* make `z` the same as `y`: `z` is still attached to the object `x ` is
585- /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the
586- /// same allocated object.
584+ /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
585+ /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z ` is still
586+ /// attached to the object `x` is attached to , and dereferencing it is Undefined Behavior unless
587+ /// `x` and `y` point into the same allocated object.
587588 ///
588589 /// Compared to [`add`], this method basically delays the requirement of staying within the
589590 /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object
590591 /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a
591592 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`]
592593 /// can be optimized better and is thus preferable in performance-sensitive code.
593594 ///
595+ /// The delayed check only considers the value of the pointer that was dereferenced, not the
596+ /// intermediate values used during the computation of the final result. For example,
594597 /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
595598 /// allocated object and then re-entering it later is permitted.
596599 ///
@@ -643,17 +646,19 @@ impl<T: ?Sized> *const T {
643646 /// It may *not* be used to access a different allocated object. Note that in Rust, every
644647 /// (stack-allocated) variable is considered a separate allocated object.
645648 ///
646- /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) /
647- /// size_of::<T>())` does *not* make `z` the same as `y`: `z` is still attached to the object `x ` is
648- /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the
649- /// same allocated object.
649+ /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
650+ /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z ` is still
651+ /// attached to the object `x` is attached to , and dereferencing it is Undefined Behavior unless
652+ /// `x` and `y` point into the same allocated object.
650653 ///
651654 /// Compared to [`sub`], this method basically delays the requirement of staying within the
652655 /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object
653656 /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a
654657 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`]
655658 /// can be optimized better and is thus preferable in performance-sensitive code.
656659 ///
660+ /// The delayed check only considers the value of the pointer that was dereferenced, not the
661+ /// intermediate values used during the computation of the final result. For example,
657662 /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
658663 /// allocated object and then re-entering it later is permitted.
659664 ///
0 commit comments