Rollup merge of #129091 - RalfJung:box_as_ptr, r=Amanieu

add Box::as_ptr and Box::as_mut_ptr methods

Unstably implements https://github.com/rust-lang/libs-team/issues/355. Tracking issue: https://github.com/rust-lang/rust/issues/129090.

r? libs-api
This commit is contained in:
Matthias Krüger 2024-08-25 16:51:03 +02:00 committed by GitHub
commit 7edbd6353b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 93 additions and 6 deletions

View File

@ -34,6 +34,7 @@
#![feature(allocator_api)]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_as_ptr)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]
#![feature(const_option)]

View File

@ -62,13 +62,11 @@ fn zeroed(size: Size, _align: Align) -> Option<Self> {
}
fn as_mut_ptr(&mut self) -> *mut u8 {
// Carefully avoiding any intermediate references.
ptr::addr_of_mut!(**self).cast()
Box::as_mut_ptr(self).cast()
}
fn as_ptr(&self) -> *const u8 {
// Carefully avoiding any intermediate references.
ptr::addr_of!(**self).cast()
Box::as_ptr(self).cast()
}
}

View File

@ -1254,6 +1254,95 @@ pub fn into_unique(b: Self) -> (Unique<T>, A) {
unsafe { (Unique::from(&mut *ptr), alloc) }
}
/// Returns a raw mutable pointer to the `Box`'s contents.
///
/// The caller must ensure that the `Box` outlives the pointer this
/// function returns, or else it will end up dangling.
///
/// This method guarantees that for the purpose of the aliasing model, this method
/// does not materialize a reference to the underlying memory, 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 memory
/// may still invalidate this pointer.
/// See the example below for how this guarantee can be used.
///
/// # Examples
///
/// Due to the aliasing guarantee, the following code is legal:
///
/// ```rust
/// #![feature(box_as_ptr)]
///
/// unsafe {
/// let mut b = Box::new(0);
/// let ptr1 = Box::as_mut_ptr(&mut b);
/// ptr1.write(1);
/// let ptr2 = Box::as_mut_ptr(&mut b);
/// ptr2.write(2);
/// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
/// ptr1.write(3);
/// }
/// ```
///
/// [`as_mut_ptr`]: Self::as_mut_ptr
/// [`as_ptr`]: Self::as_ptr
#[unstable(feature = "box_as_ptr", issue = "129090")]
#[rustc_never_returns_null_ptr]
#[inline]
pub fn as_mut_ptr(b: &mut Self) -> *mut T {
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
// any references.
ptr::addr_of_mut!(**b)
}
/// Returns a raw pointer to the `Box`'s contents.
///
/// The caller must ensure that the `Box` outlives the pointer this
/// function returns, or else it will end up dangling.
///
/// The caller must also ensure that the memory the pointer (non-transitively) points to
/// 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 `Box`, use [`as_mut_ptr`].
///
/// This method guarantees that for the purpose of the aliasing model, this method
/// does not materialize a reference to the underlying memory, 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 memory,
/// as well as writing to this memory, may still invalidate this pointer.
/// See the example below for how this guarantee can be used.
///
/// # Examples
///
/// Due to the aliasing guarantee, the following code is legal:
///
/// ```rust
/// #![feature(box_as_ptr)]
///
/// unsafe {
/// let mut v = Box::new(0);
/// let ptr1 = Box::as_ptr(&v);
/// let ptr2 = Box::as_mut_ptr(&mut v);
/// let _val = ptr2.read();
/// // No write to this memory has happened yet, so `ptr1` is still valid.
/// let _val = ptr1.read();
/// // However, once we do a write...
/// ptr2.write(1);
/// // ... `ptr1` is no longer valid.
/// // This would be UB: let _val = ptr1.read();
/// }
/// ```
///
/// [`as_mut_ptr`]: Self::as_mut_ptr
/// [`as_ptr`]: Self::as_ptr
#[unstable(feature = "box_as_ptr", issue = "129090")]
#[rustc_never_returns_null_ptr]
#[inline]
pub fn as_ptr(b: &Self) -> *const T {
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
// any references.
ptr::addr_of!(**b)
}
/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have

View File

@ -1334,7 +1334,7 @@ pub fn as_ptr(&self) -> *const T {
self.buf.ptr()
}
/// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
/// Returns a raw mutable pointer to the vector's buffer, or a dangling
/// raw pointer valid for zero sized reads if the vector didn't allocate.
///
/// The caller must ensure that the vector outlives the pointer this
@ -1350,7 +1350,6 @@ pub fn as_ptr(&self) -> *const T {
/// may still invalidate this pointer.
/// See the second example below for how this guarantee can be used.
///
///
/// # Examples
///
/// ```