Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1753,7 +1753,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
///
/// 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`].
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`].
/// 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.
Expand All @@ -1776,6 +1776,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
///
/// [`as_mut_ptr`]: Self::as_mut_ptr
/// [`as_ptr`]: Self::as_ptr
/// [`as_non_null`]: Self::as_non_null
#[must_use]
#[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_never_returns_null_ptr]
#[rustc_as_ptr]
Expand All @@ -1797,7 +1799,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
///
/// 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`].
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`].
/// 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.
Expand All @@ -1823,6 +1825,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
///
/// [`as_mut_ptr`]: Self::as_mut_ptr
/// [`as_ptr`]: Self::as_ptr
/// [`as_non_null`]: Self::as_non_null
#[must_use]
#[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")]
#[rustc_never_returns_null_ptr]
#[rustc_as_ptr]
Expand All @@ -1833,6 +1837,48 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
&raw const **b
}

/// Returns a `NonNull` 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`], [`as_mut_ptr`], and [`as_non_null`].
/// 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_non_null)]
///
/// unsafe {
/// let mut b = Box::new(0);
/// let ptr1 = Box::as_non_null(&mut b);
/// ptr1.write(1);
/// let ptr2 = Box::as_non_null(&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
/// [`as_non_null`]: Self::as_non_null
#[must_use]
#[unstable(feature = "box_as_non_null", issue = "157345")]
#[rustc_as_ptr]
#[inline]
pub fn as_non_null(b: &mut Self) -> NonNull<T> {
// SAFETY: `Box` is guaranteed to be non-null.
unsafe { NonNull::new_unchecked(Self::as_mut_ptr(b)) }
}

/// Returns a reference to the underlying allocator.
///
/// Note: this is an associated function, which means that you have
Expand Down
Loading