about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2023-07-26 18:41:37 -0700
committerManish Goregaokar <manishsmail@gmail.com>2023-08-12 09:19:23 -0700
commit3809c091fc25339f606d510b3835182b0cd0dbc7 (patch)
tree0e35196cf611f706f0006ea99811492fc0fda6b5
parent778fdf2dfb0e110d2cf955b827c3d9cfe147235b (diff)
downloadrust-3809c091fc25339f606d510b3835182b0cd0dbc7.tar.gz
rust-3809c091fc25339f606d510b3835182b0cd0dbc7.zip
aliasing guarantee
-rw-r--r--library/alloc/src/vec/mod.rs65
1 files changed, 40 insertions, 25 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 565865231e7..626e2f5f0fa 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1218,11 +1218,14 @@ impl<T, A: Allocator> Vec<T, A> {
     /// 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`].
     ///
-    /// This method guarantees that when it is called multiple times without
-    /// the buffer being reallocated in the mean time, the returned pointer will
-    /// always be exactly the same, even for the purpose of the aliasing model, where
-    /// pointers may be invalidated even when the actual memory does not move.
-    /// See the second example below for how this can be used.
+    /// This method guarantees that for the purpose of the aliasing model, this method
+    /// does not materialize a reference to the underlying slice, and thus the returned pointer
+    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`],
+    /// Note that calling other methods that materialize mutable references to the slice,
+    /// 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
     ///
@@ -1237,17 +1240,22 @@ impl<T, A: Allocator> Vec<T, A> {
     /// }
     /// ```
     ///
-    /// The validity guarantee works out this way:
+    /// Due to the aliasing guarantee, the following code is legal:
     ///
     /// ```rust
-    /// let mut v = vec![0];
-    /// let ptr = v.as_ptr();
-    /// let x = ptr.read();
-    /// v[0] = 5;
-    /// // Notably, the write above did *not* invalidate `ptr1`:
-    /// let x = ptr.read();
+    /// unsafe {
+    ///     let mut v = vec![0];
+    ///     let ptr1 = v.as_ptr();
+    ///     let _ = ptr1.read();
+    ///     let ptr2 = v.as_mut_ptr();
+    ///     ptr2.write(2);
+    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ///     let _ = ptr1.read();
+    /// }
     /// ```
+    ///
     /// [`as_mut_ptr`]: Vec::as_mut_ptr
+    /// [`as_ptr`]: Vec::as_ptr
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
     #[inline]
     pub fn as_ptr(&self) -> *const T {
@@ -1264,11 +1272,13 @@ impl<T, A: Allocator> Vec<T, A> {
     /// Modifying the vector may cause its buffer to be reallocated,
     /// which would also make any pointers to it invalid.
     ///
-    /// This method guarantees that when it is called multiple times without
-    /// the buffer being reallocated in the mean time, the returned pointer will
-    /// always be exactly the same, even for the purpose of the aliasing model, where
-    /// pointers may be invalidated even when the actual memory does not move.
-    /// See the second example below for how this can be used.
+    /// This method guarantees that for the purpose of the aliasing model, this method
+    /// does not materialize a reference to the underlying slice, and thus the returned pointer
+    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`],
+    /// Note that calling other methods that materialize references to the slice,
+    /// 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
@@ -1289,17 +1299,22 @@ impl<T, A: Allocator> Vec<T, A> {
     /// 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
-    /// let mut v = vec![0];
-    /// let ptr1 = v.as_mut_ptr();
-    /// ptr1.write(1);
-    /// let ptr2 = v.as_mut_ptr();
-    /// ptr2.write(2);
-    /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
-    /// ptr1.write(3);
+    /// unsafe {
+    ///     let mut v = vec![0];
+    ///     let ptr1 = v.as_mut_ptr();
+    ///     ptr1.write(1);
+    ///     let ptr2 = v.as_mut_ptr();
+    ///     ptr2.write(2);
+    ///     // 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")]
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut T {