From 3809c091fc25339f606d510b3835182b0cd0dbc7 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 26 Jul 2023 18:41:37 -0700 Subject: [PATCH] aliasing guarantee --- library/alloc/src/vec/mod.rs | 65 ++++++++++++++++++++++-------------- 1 file 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 @@ pub fn as_mut_slice(&mut self) -> &mut [T] { /// 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 @@ 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 - /// 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 @@ pub fn as_ptr(&self) -> *const T { /// 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 @@ pub fn as_ptr(&self) -> *const T { /// 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 {