Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1241f19

Browse files
committed
offset_from: also document same-provenance requirement
1 parent c5a8b7b commit 1241f19

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

library/core/src/ptr/const_ptr.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ impl<T: ?Sized> *const T {
303303
/// byte past the end of the same allocated object. Note that in Rust,
304304
/// every (stack-allocated) variable is considered a separate allocated object.
305305
///
306+
/// * Both pointers must be *derived from* a pointer to the same object.
307+
/// (See below for an example.)
308+
///
306309
/// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
307310
///
308311
/// * The distance between the pointers, in bytes, must be an exact multiple
@@ -348,6 +351,25 @@ impl<T: ?Sized> *const T {
348351
/// assert_eq!(ptr2.offset(-2), ptr1);
349352
/// }
350353
/// ```
354+
///
355+
/// *Incorrect* usage:
356+
///
357+
/// ```rust,no_run
358+
/// #![feature(ptr_offset_from)]
359+
///
360+
/// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
361+
/// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
362+
/// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
363+
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
364+
/// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff);
365+
/// assert_eq!(ptr2 as usize, ptr2_other as usize);
366+
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
367+
/// // computing their offset is undefined behavior, even though
368+
/// // they point to the same address!
369+
/// unsafe {
370+
/// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
371+
/// }
372+
/// ```
351373
#[unstable(feature = "ptr_offset_from", issue = "41079")]
352374
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
353375
#[inline]

library/core/src/ptr/mut_ptr.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,9 @@ impl<T: ?Sized> *mut T {
474474
/// byte past the end of the same allocated object. Note that in Rust,
475475
/// every (stack-allocated) variable is considered a separate allocated object.
476476
///
477+
/// * Both pointers must be *derived from* a pointer to the same object.
478+
/// (See below for an example.)
479+
///
477480
/// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
478481
///
479482
/// * The distance between the pointers, in bytes, must be an exact multiple
@@ -519,6 +522,25 @@ impl<T: ?Sized> *mut T {
519522
/// assert_eq!(ptr2.offset(-2), ptr1);
520523
/// }
521524
/// ```
525+
///
526+
/// *Incorrect* usage:
527+
///
528+
/// ```rust,no_run
529+
/// #![feature(ptr_offset_from)]
530+
///
531+
/// let ptr1 = Box::into_raw(Box::new(0u8));
532+
/// let ptr2 = Box::into_raw(Box::new(1u8));
533+
/// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
534+
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
535+
/// let ptr2_other = (ptr1 as *mut u8).wrapping_offset(diff);
536+
/// assert_eq!(ptr2 as usize, ptr2_other as usize);
537+
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
538+
/// // computing their offset is undefined behavior, even though
539+
/// // they point to the same address!
540+
/// unsafe {
541+
/// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
542+
/// }
543+
/// ```
522544
#[unstable(feature = "ptr_offset_from", issue = "41079")]
523545
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
524546
#[inline]

0 commit comments

Comments
 (0)