@@ -232,23 +232,26 @@ impl<T: ?Sized> *const T {
232
232
///
233
233
/// # Safety
234
234
///
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.
237
236
///
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.
242
240
///
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.
246
245
///
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.
252
255
///
253
256
/// If you need to cross object boundaries, cast the pointer to an integer and
254
257
/// do the arithmetic there.
@@ -571,19 +574,25 @@ impl<T: ?Sized> *const T {
571
574
///
572
575
/// # Safety
573
576
///
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.
576
587
///
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.
581
593
///
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.
587
596
///
588
597
/// If you need to cross object boundaries, cast the pointer to an integer and
589
598
/// do the arithmetic there.
@@ -628,19 +637,25 @@ impl<T: ?Sized> *const T {
628
637
///
629
638
/// # Safety
630
639
///
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.
633
650
///
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.
638
656
///
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.
644
659
///
645
660
/// If you need to cross object boundaries, cast the pointer to an integer and
646
661
/// do the arithmetic there.
0 commit comments