diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index b511466acd6..abe40fd96d0 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -184,8 +184,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -210,6 +209,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// enables more aggressive compiler optimizations. /// /// [`wrapping_offset`]: #method.wrapping_offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -245,9 +245,8 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -269,6 +268,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// do the arithmetic there. /// /// [`offset`]: #method.offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -314,8 +314,7 @@ pub const fn wrapping_offset(self, count: isize) -> *const T /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. /// (See below for an example.) @@ -345,6 +344,7 @@ pub const fn wrapping_offset(self, count: isize) -> *const T /// such large allocations either.) /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Panics /// @@ -468,8 +468,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -494,6 +493,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// enables more aggressive compiler optimizations. /// /// [`wrapping_add`]: #method.wrapping_add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -532,8 +532,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -558,6 +557,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -594,9 +594,8 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -618,6 +617,7 @@ pub const fn guaranteed_ne(self, other: *const T) -> bool /// do the arithmetic there. /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -659,9 +659,8 @@ pub const fn wrapping_add(self, count: usize) -> Self /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -683,6 +682,7 @@ pub const fn wrapping_add(self, count: usize) -> Self /// do the arithmetic there. /// /// [`sub`]: #method.sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -997,7 +997,7 @@ pub unsafe fn get_unchecked(self, index: I) -> *const I::Output /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1019,6 +1019,7 @@ pub unsafe fn get_unchecked(self, index: I) -> *const I::Output /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 7e4f8d570a7..d2f90c7fc8c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -55,6 +55,14 @@ //! has size 0, i.e., even if memory is not actually touched. Consider using //! [`NonNull::dangling`] in such cases. //! +//! ## Allocated object +//! +//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an +//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory. +//! Common examples of allocated objects include stack-allocated variables (each variable is a +//! separate allocated object), heap allocations (each allocation created by the global allocator is +//! a separate allocated object), and `static` variables. +//! //! [aliasing]: ../../nomicon/aliasing.html //! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fa09cf85435..51ddc7da8a4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -189,8 +189,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -215,6 +214,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// enables more aggressive compiler optimizations. /// /// [`wrapping_offset`]: #method.wrapping_offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -251,9 +251,8 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -275,6 +274,7 @@ pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> /// do the arithmetic there. /// /// [`offset`]: #method.offset + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -485,8 +485,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// Behavior: /// /// * Both the starting and other pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. /// (See below for an example.) @@ -516,6 +515,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// such large allocations either.) /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Panics /// @@ -575,8 +575,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -639,8 +638,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// byte past the end of the same [allocated object]. /// /// * The computed offset cannot exceed `isize::MAX` **bytes**. /// @@ -665,6 +663,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// enables more aggressive compiler optimizations. /// /// [`wrapping_sub`]: #method.wrapping_sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -701,9 +700,8 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -725,6 +723,7 @@ pub const fn guaranteed_eq(self, other: *mut T) -> bool /// do the arithmetic there. /// /// [`add`]: #method.add + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -766,9 +765,8 @@ pub const fn wrapping_add(self, count: usize) -> Self /// /// This operation itself is always safe, but using the resulting pointer is not. /// - /// The resulting pointer remains attached to the same allocated object that `self` points to. - /// It may *not* be used to access a different allocated object. Note that in Rust, every - /// (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same [allocated object] that `self` points to. + /// It may *not* be used to access a different allocated object. /// /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still @@ -790,6 +788,7 @@ pub const fn wrapping_add(self, count: usize) -> Self /// do the arithmetic there. /// /// [`sub`]: #method.sub + /// [allocated object]: crate::ptr#allocated-object /// /// # Examples /// @@ -1261,7 +1260,7 @@ pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::()` many bytes, /// and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1283,6 +1282,7 @@ pub unsafe fn get_unchecked_mut(self, index: I) -> *mut I::Output /// See also [`slice::from_raw_parts`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { @@ -1311,7 +1311,7 @@ pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::()` /// many bytes, and it must be properly aligned. This means in particular: /// - /// * The entire memory range of this slice must be contained within a single allocated object! + /// * The entire memory range of this slice must be contained within a single [allocated object]! /// Slices can never span across multiple allocated objects. /// /// * The pointer must be aligned even for zero-length slices. One @@ -1333,6 +1333,7 @@ pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { /// See also [`slice::from_raw_parts_mut`][]. /// /// [valid]: crate::ptr#safety + /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit]> {