diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2023-07-26 18:41:37 -0700 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2023-08-12 09:19:23 -0700 |
| commit | 3809c091fc25339f606d510b3835182b0cd0dbc7 (patch) | |
| tree | 0e35196cf611f706f0006ea99811492fc0fda6b5 | |
| parent | 778fdf2dfb0e110d2cf955b827c3d9cfe147235b (diff) | |
| download | rust-3809c091fc25339f606d510b3835182b0cd0dbc7.tar.gz rust-3809c091fc25339f606d510b3835182b0cd0dbc7.zip | |
aliasing guarantee
| -rw-r--r-- | library/alloc/src/vec/mod.rs | 65 |
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 { |
