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:
commit
7edbd6353b
@ -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)]
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
///
|
||||
/// ```
|
||||
|
Loading…
Reference in New Issue
Block a user