aliasing guarantee

This commit is contained in:
Manish Goregaokar 2023-07-26 18:41:37 -07:00
parent 778fdf2dfb
commit 3809c091fc

View File

@ -1218,11 +1218,14 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
/// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`]. /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
/// ///
/// This method guarantees that when it is called multiple times without /// This method guarantees that for the purpose of the aliasing model, this method
/// the buffer being reallocated in the mean time, the returned pointer will /// does not materialize a reference to the underlying slice, and thus the returned pointer
/// always be exactly the same, even for the purpose of the aliasing model, where /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`],
/// pointers may be invalidated even when the actual memory does not move. /// Note that calling other methods that materialize mutable references to the slice,
/// See the second example below for how this can be used. /// or references to specific elements you are planning on accessing through this pointer,
/// may still invalidate this pointer.
/// See the second example below for how this guarantee can be used.
///
/// ///
/// # Examples /// # Examples
/// ///
@ -1237,17 +1240,22 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
/// } /// }
/// ``` /// ```
/// ///
/// The validity guarantee works out this way: /// Due to the aliasing guarantee, the following code is legal:
/// ///
/// ```rust /// ```rust
/// let mut v = vec![0]; /// unsafe {
/// let ptr = v.as_ptr(); /// let mut v = vec![0];
/// let x = ptr.read(); /// let ptr1 = v.as_ptr();
/// v[0] = 5; /// let _ = ptr1.read();
/// // Notably, the write above did *not* invalidate `ptr1`: /// let ptr2 = v.as_mut_ptr();
/// let x = ptr.read(); /// ptr2.write(2);
/// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
/// let _ = ptr1.read();
/// }
/// ``` /// ```
///
/// [`as_mut_ptr`]: Vec::as_mut_ptr /// [`as_mut_ptr`]: Vec::as_mut_ptr
/// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")] #[stable(feature = "vec_as_ptr", since = "1.37.0")]
#[inline] #[inline]
pub fn as_ptr(&self) -> *const T { pub fn as_ptr(&self) -> *const T {
@ -1264,11 +1272,13 @@ pub fn as_ptr(&self) -> *const T {
/// Modifying the vector may cause its buffer to be reallocated, /// Modifying the vector may cause its buffer to be reallocated,
/// which would also make any pointers to it invalid. /// which would also make any pointers to it invalid.
/// ///
/// This method guarantees that when it is called multiple times without /// This method guarantees that for the purpose of the aliasing model, this method
/// the buffer being reallocated in the mean time, the returned pointer will /// does not materialize a reference to the underlying slice, and thus the returned pointer
/// always be exactly the same, even for the purpose of the aliasing model, where /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`],
/// pointers may be invalidated even when the actual memory does not move. /// Note that calling other methods that materialize references to the slice,
/// See the second example below for how this can be used. /// or references to specific elements you are planning on accessing through this pointer,
/// may still invalidate this pointer.
/// See the second example below for how this guarantee can be used.
/// ///
/// ///
/// # Examples /// # Examples
@ -1289,17 +1299,22 @@ pub fn as_ptr(&self) -> *const T {
/// assert_eq!(&*x, &[0, 1, 2, 3]); /// assert_eq!(&*x, &[0, 1, 2, 3]);
/// ``` /// ```
/// ///
/// The validity guarantee works out this way: /// Due to the aliasing guarantee, the following code is legal:
/// ///
/// ```rust /// ```rust
/// let mut v = vec![0]; /// unsafe {
/// let ptr1 = v.as_mut_ptr(); /// let mut v = vec![0];
/// ptr1.write(1); /// let ptr1 = v.as_mut_ptr();
/// let ptr2 = v.as_mut_ptr(); /// ptr1.write(1);
/// ptr2.write(2); /// let ptr2 = v.as_mut_ptr();
/// // Notably, the write to `ptr2` did *not* invalidate `ptr1`: /// ptr2.write(2);
/// ptr1.write(3); /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
/// ptr1.write(3);
/// }
/// ``` /// ```
///
/// [`as_mut_ptr`]: Vec::as_mut_ptr
/// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")] #[stable(feature = "vec_as_ptr", since = "1.37.0")]
#[inline] #[inline]
pub fn as_mut_ptr(&mut self) -> *mut T { pub fn as_mut_ptr(&mut self) -> *mut T {