@@ -232,23 +232,26 @@ impl<T: ?Sized> *const T {
232232 ///
233233 /// # Safety
234234 ///
235- /// The resulting pointer does not need to be in bounds, but it is
236- /// potentially hazardous to dereference (which requires `unsafe`).
235+ /// This operation itself is always safe, but using the resulting pointer is not.
237236 ///
238- /// In particular, the resulting pointer remains attached to the same allocated
239- /// object that `self` points to. It may *not* be used to access a
240- /// different allocated object. Note that in Rust,
241- /// every (stack-allocated) variable is considered a separate allocated object.
237+ /// The resulting pointer remains attached to the same allocated object that `self` points to.
238+ /// It may *not* be used to access a different allocated object. Note that in Rust, every
239+ /// (stack-allocated) variable is considered a separate allocated object.
242240 ///
243- /// In other words, `x.wrapping_offset((y as usize).wrapping_sub(x as usize) / size_of::<T>())`
244- /// is *not* the same as `y`, and dereferencing it is undefined behavior
245- /// unless `x` and `y` point into the same allocated object.
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.
246245 ///
247- /// Compared to [`offset`], this method basically delays the requirement of staying
248- /// within the same allocated object: [`offset`] is immediate Undefined Behavior when
249- /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads
250- /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized
251- /// better and is thus preferable in performance-sensitive code.
246+ /// Compared to [`offset`], this method basically delays the requirement of staying within the
247+ /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object
248+ /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a
249+ /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`]
250+ /// can be optimized better and is thus preferable in performance-sensitive code.
251+ ///
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.
252255 ///
253256 /// If you need to cross object boundaries, cast the pointer to an integer and
254257 /// do the arithmetic there.
@@ -571,19 +574,25 @@ impl<T: ?Sized> *const T {
571574 ///
572575 /// # Safety
573576 ///
574- /// The resulting pointer does not need to be in bounds, but it is
575- /// potentially hazardous to dereference (which requires `unsafe`).
577+ /// This operation itself is always safe, but using the resulting pointer is not.
578+ ///
579+ /// The resulting pointer remains attached to the same allocated object that `self` points to.
580+ /// It may *not* be used to access a different allocated object. Note that in Rust, every
581+ /// (stack-allocated) variable is considered a separate allocated object.
582+ ///
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.
576587 ///
577- /// In particular, the resulting pointer remains attached to the same allocated
578- /// object that `self` points to. It may *not* be used to access a
579- /// different allocated object. Note that in Rust,
580- /// every (stack-allocated) variable is considered a separate allocated object.
588+ /// Compared to [`add`], this method basically delays the requirement of staying within the
589+ /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object
590+ /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a
591+ /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`]
592+ /// can be optimized better and is thus preferable in performance-sensitive code.
581593 ///
582- /// Compared to [`add`], this method basically delays the requirement of staying
583- /// within the same allocated object: [`add`] is immediate Undefined Behavior when
584- /// crossing object boundaries; `wrapping_add` produces a pointer but still leads
585- /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized
586- /// better and is thus preferable in performance-sensitive code.
594+ /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
595+ /// allocated object and then re-entering it later is permitted.
587596 ///
588597 /// If you need to cross object boundaries, cast the pointer to an integer and
589598 /// do the arithmetic there.
@@ -628,19 +637,25 @@ impl<T: ?Sized> *const T {
628637 ///
629638 /// # Safety
630639 ///
631- /// The resulting pointer does not need to be in bounds, but it is
632- /// potentially hazardous to dereference (which requires `unsafe`).
640+ /// This operation itself is always safe, but using the resulting pointer is not.
641+ ///
642+ /// The resulting pointer remains attached to the same allocated object that `self` points to.
643+ /// It may *not* be used to access a different allocated object. Note that in Rust, every
644+ /// (stack-allocated) variable is considered a separate allocated object.
645+ ///
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.
633650 ///
634- /// In particular, the resulting pointer remains attached to the same allocated
635- /// object that `self` points to. It may *not* be used to access a
636- /// different allocated object. Note that in Rust,
637- /// every (stack-allocated) variable is considered a separate allocated object.
651+ /// Compared to [`sub`], this method basically delays the requirement of staying within the
652+ /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object
653+ /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a
654+ /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`]
655+ /// can be optimized better and is thus preferable in performance-sensitive code.
638656 ///
639- /// Compared to [`sub`], this method basically delays the requirement of staying
640- /// within the same allocated object: [`sub`] is immediate Undefined Behavior when
641- /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads
642- /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized
643- /// better and is thus preferable in performance-sensitive code.
657+ /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
658+ /// allocated object and then re-entering it later is permitted.
644659 ///
645660 /// If you need to cross object boundaries, cast the pointer to an integer and
646661 /// do the arithmetic there.
0 commit comments