From fa2ffcfb8edb7750be1f2f4ac8e3c900183d3570 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Wed, 3 Jun 2026 07:48:15 +0700 Subject: [PATCH 1/2] Add `must_use` to `Box::as_{ptr,mut_ptr}` --- library/alloc/src/boxed.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 3087a7d2004bc..1237f5da2c532 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1776,6 +1776,7 @@ impl Box { /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr + #[must_use] #[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] @@ -1823,6 +1824,7 @@ impl Box { /// /// [`as_mut_ptr`]: Self::as_mut_ptr /// [`as_ptr`]: Self::as_ptr + #[must_use] #[stable(feature = "box_as_ptr", since = "CURRENT_RUSTC_VERSION")] #[rustc_never_returns_null_ptr] #[rustc_as_ptr] From 5a398727fd6ad0be0609a0694382b4c2a9cec8ba Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Wed, 3 Jun 2026 07:55:56 +0700 Subject: [PATCH 2/2] Implement `Box::as_non_null()`. ACP: Tracking issue: The docs are mostly copied from `Box::as_mut_ptr()` --- library/alloc/src/boxed.rs | 48 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1237f5da2c532..40e0d8cacfff1 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1753,7 +1753,7 @@ impl Box { /// /// 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. @@ -1776,6 +1776,7 @@ impl Box { /// /// [`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] @@ -1798,7 +1799,7 @@ impl Box { /// /// 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. @@ -1824,6 +1825,7 @@ impl Box { /// /// [`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] @@ -1835,6 +1837,48 @@ impl Box { &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 { + // 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