Skip to content

Commit b3bc402

Browse files
Rollup merge of #157347 - theemathas:box-as-non-null, r=Darksonn
Implement `Box::as_non_null()`. ACP: <rust-lang/libs-team#799> Tracking issue: <#157345> The docs are mostly copied from `Box::as_mut_ptr()` I also made a drive-by change to add `#[must_use]` to `Box::as_{ptr, mut_ptr}`. I'm unsure what `#[rustc_never_returns_null_ptr]` and `#[rustc_as_ptr]` do. Should `Box::as_non_null()` be annotated with them? r? libs-api
2 parents 0c72496 + 5a39872 commit b3bc402

1 file changed

Lines changed: 48 additions & 2 deletions

File tree

library/alloc/src/boxed.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
17531753
///
17541754
/// This method guarantees that for the purpose of the aliasing model, this method
17551755
/// does not materialize a reference to the underlying memory, and thus the returned pointer
1756-
/// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1756+
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`].
17571757
/// Note that calling other methods that materialize references to the memory
17581758
/// may still invalidate this pointer.
17591759
/// See the example below for how this guarantee can be used.
@@ -1776,6 +1776,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
17761776
///
17771777
/// [`as_mut_ptr`]: Self::as_mut_ptr
17781778
/// [`as_ptr`]: Self::as_ptr
1779+
/// [`as_non_null`]: Self::as_non_null
1780+
#[must_use]
17791781
#[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")]
17801782
#[rustc_never_returns_null_ptr]
17811783
#[rustc_as_ptr]
@@ -1797,7 +1799,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
17971799
///
17981800
/// This method guarantees that for the purpose of the aliasing model, this method
17991801
/// does not materialize a reference to the underlying memory, and thus the returned pointer
1800-
/// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1802+
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`].
18011803
/// Note that calling other methods that materialize mutable references to the memory,
18021804
/// as well as writing to this memory, may still invalidate this pointer.
18031805
/// See the example below for how this guarantee can be used.
@@ -1823,6 +1825,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
18231825
///
18241826
/// [`as_mut_ptr`]: Self::as_mut_ptr
18251827
/// [`as_ptr`]: Self::as_ptr
1828+
/// [`as_non_null`]: Self::as_non_null
1829+
#[must_use]
18261830
#[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")]
18271831
#[rustc_never_returns_null_ptr]
18281832
#[rustc_as_ptr]
@@ -1833,6 +1837,48 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
18331837
&raw const **b
18341838
}
18351839

1840+
/// Returns a `NonNull` pointer to the `Box`'s contents.
1841+
///
1842+
/// The caller must ensure that the `Box` outlives the pointer this
1843+
/// function returns, or else it will end up dangling.
1844+
///
1845+
/// This method guarantees that for the purpose of the aliasing model, this method
1846+
/// does not materialize a reference to the underlying memory, and thus the returned pointer
1847+
/// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`], and [`as_non_null`].
1848+
/// Note that calling other methods that materialize references to the memory
1849+
/// may still invalidate this pointer.
1850+
/// See the example below for how this guarantee can be used.
1851+
///
1852+
/// # Examples
1853+
///
1854+
/// Due to the aliasing guarantee, the following code is legal:
1855+
///
1856+
/// ```rust
1857+
/// #![feature(box_as_non_null)]
1858+
///
1859+
/// unsafe {
1860+
/// let mut b = Box::new(0);
1861+
/// let ptr1 = Box::as_non_null(&mut b);
1862+
/// ptr1.write(1);
1863+
/// let ptr2 = Box::as_non_null(&mut b);
1864+
/// ptr2.write(2);
1865+
/// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
1866+
/// ptr1.write(3);
1867+
/// }
1868+
/// ```
1869+
///
1870+
/// [`as_mut_ptr`]: Self::as_mut_ptr
1871+
/// [`as_ptr`]: Self::as_ptr
1872+
/// [`as_non_null`]: Self::as_non_null
1873+
#[must_use]
1874+
#[unstable(feature = "box_as_non_null", issue = "157345")]
1875+
#[rustc_as_ptr]
1876+
#[inline]
1877+
pub fn as_non_null(b: &mut Self) -> NonNull<T> {
1878+
// SAFETY: `Box` is guaranteed to be non-null.
1879+
unsafe { NonNull::new_unchecked(Self::as_mut_ptr(b)) }
1880+
}
1881+
18361882
/// Returns a reference to the underlying allocator.
18371883
///
18381884
/// Note: this is an associated function, which means that you have

0 commit comments

Comments
 (0)