@@ -1584,7 +1584,8 @@ impl<T, A: Allocator> Vec<T, A> {
15841584 ///
15851585 /// This method guarantees that for the purpose of the aliasing model, this method
15861586 /// does not materialize a reference to the underlying slice, and thus the returned pointer
1587- /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1587+ /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
1588+ /// and [`as_non_null`].
15881589 /// Note that calling other methods that materialize mutable references to the slice,
15891590 /// or mutable references to specific elements you are planning on accessing through this pointer,
15901591 /// as well as writing to those elements, may still invalidate this pointer.
@@ -1621,6 +1622,7 @@ impl<T, A: Allocator> Vec<T, A> {
16211622 ///
16221623 /// [`as_mut_ptr`]: Vec::as_mut_ptr
16231624 /// [`as_ptr`]: Vec::as_ptr
1625+ /// [`as_non_null`]: Vec::as_non_null
16241626 #[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
16251627 #[ rustc_never_returns_null_ptr]
16261628 #[ inline]
@@ -1640,7 +1642,8 @@ impl<T, A: Allocator> Vec<T, A> {
16401642 ///
16411643 /// This method guarantees that for the purpose of the aliasing model, this method
16421644 /// does not materialize a reference to the underlying slice, and thus the returned pointer
1643- /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1645+ /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
1646+ /// and [`as_non_null`].
16441647 /// Note that calling other methods that materialize references to the slice,
16451648 /// or references to specific elements you are planning on accessing through this pointer,
16461649 /// may still invalidate this pointer.
@@ -1680,6 +1683,7 @@ impl<T, A: Allocator> Vec<T, A> {
16801683 ///
16811684 /// [`as_mut_ptr`]: Vec::as_mut_ptr
16821685 /// [`as_ptr`]: Vec::as_ptr
1686+ /// [`as_non_null`]: Vec::as_non_null
16831687 #[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
16841688 #[ rustc_never_returns_null_ptr]
16851689 #[ inline]
@@ -1689,6 +1693,69 @@ impl<T, A: Allocator> Vec<T, A> {
16891693 self . buf . ptr ( )
16901694 }
16911695
1696+ /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
1697+ /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
1698+ ///
1699+ /// The caller must ensure that the vector outlives the pointer this
1700+ /// function returns, or else it will end up dangling.
1701+ /// Modifying the vector may cause its buffer to be reallocated,
1702+ /// which would also make any pointers to it invalid.
1703+ ///
1704+ /// This method guarantees that for the purpose of the aliasing model, this method
1705+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
1706+ /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
1707+ /// and [`as_non_null`].
1708+ /// Note that calling other methods that materialize references to the slice,
1709+ /// or references to specific elements you are planning on accessing through this pointer,
1710+ /// may still invalidate this pointer.
1711+ /// See the second example below for how this guarantee can be used.
1712+ ///
1713+ /// # Examples
1714+ ///
1715+ /// ```
1716+ /// #![feature(box_vec_non_null)]
1717+ ///
1718+ /// // Allocate vector big enough for 4 elements.
1719+ /// let size = 4;
1720+ /// let mut x: Vec<i32> = Vec::with_capacity(size);
1721+ /// let x_ptr = x.as_non_null();
1722+ ///
1723+ /// // Initialize elements via raw pointer writes, then set length.
1724+ /// unsafe {
1725+ /// for i in 0..size {
1726+ /// x_ptr.add(i).write(i as i32);
1727+ /// }
1728+ /// x.set_len(size);
1729+ /// }
1730+ /// assert_eq!(&*x, &[0, 1, 2, 3]);
1731+ /// ```
1732+ ///
1733+ /// Due to the aliasing guarantee, the following code is legal:
1734+ ///
1735+ /// ```rust
1736+ /// #![feature(box_vec_non_null)]
1737+ ///
1738+ /// unsafe {
1739+ /// let mut v = vec![0];
1740+ /// let ptr1 = v.as_non_null();
1741+ /// ptr1.write(1);
1742+ /// let ptr2 = v.as_non_null();
1743+ /// ptr2.write(2);
1744+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
1745+ /// ptr1.write(3);
1746+ /// }
1747+ /// ```
1748+ ///
1749+ /// [`as_mut_ptr`]: Vec::as_mut_ptr
1750+ /// [`as_ptr`]: Vec::as_ptr
1751+ /// [`as_non_null`]: Vec::as_non_null
1752+ #[ unstable( feature = "box_vec_non_null" , reason = "new API" , issue = "130364" ) ]
1753+ #[ inline]
1754+ pub fn as_non_null ( & mut self ) -> NonNull < T > {
1755+ // SAFETY: A `Vec` always has a non-null pointer.
1756+ unsafe { NonNull :: new_unchecked ( self . as_mut_ptr ( ) ) }
1757+ }
1758+
16921759 /// Returns a reference to the underlying allocator.
16931760 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
16941761 #[ inline]
0 commit comments