@@ -232,23 +232,27 @@ 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_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. 
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+      /// 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. 
252256     /// 
253257     /// If you need to cross object boundaries, cast the pointer to an integer and 
254258     /// do the arithmetic there. 
@@ -571,19 +575,27 @@ impl<T: ?Sized> *const T {
571575     /// 
572576     /// # Safety 
573577     /// 
574-      /// The resulting pointer does not need to be in bounds, but it is 
575-      /// potentially hazardous to dereference (which requires `unsafe`). 
578+      /// This operation itself is always safe, but using the resulting pointer is not. 
579+      /// 
580+      /// The resulting pointer remains attached to the same allocated object that `self` points to. 
581+      /// It may *not* be used to access a different allocated object. Note that in Rust, every 
582+      /// (stack-allocated) variable is considered a separate allocated object. 
583+      /// 
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. 
576588     /// 
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. 
589+      /// Compared to [`add`], this method basically delays the requirement of staying within the 
590+      /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object 
591+      /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a 
592+      /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] 
593+      /// can be optimized better and is thus preferable in performance-sensitive code. 
581594     /// 
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. 
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, 
597+      /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the 
598+      /// allocated object and then re-entering it later is permitted. 
587599     /// 
588600     /// If you need to cross object boundaries, cast the pointer to an integer and 
589601     /// do the arithmetic there. 
@@ -628,19 +640,27 @@ impl<T: ?Sized> *const T {
628640     /// 
629641     /// # Safety 
630642     /// 
631-      /// The resulting pointer does not need to be in bounds, but it is 
632-      /// potentially hazardous to dereference (which requires `unsafe`). 
643+      /// This operation itself is always safe, but using the resulting pointer is not. 
644+      /// 
645+      /// The resulting pointer remains attached to the same allocated object that `self` points to. 
646+      /// It may *not* be used to access a different allocated object. Note that in Rust, every 
647+      /// (stack-allocated) variable is considered a separate allocated object. 
648+      /// 
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. 
633653     /// 
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. 
654+      /// Compared to [`sub`], this method basically delays the requirement of staying within the 
655+      /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object 
656+      /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a 
657+      /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] 
658+      /// can be optimized better and is thus preferable in performance-sensitive code. 
638659     /// 
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. 
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, 
662+      /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the 
663+      /// allocated object and then re-entering it later is permitted. 
644664     /// 
645665     /// If you need to cross object boundaries, cast the pointer to an integer and 
646666     /// do the arithmetic there. 
0 commit comments