@@ -1584,7 +1584,8 @@ impl<T, A: Allocator> Vec<T, A> {
1584
1584
///
1585
1585
/// This method guarantees that for the purpose of the aliasing model, this method
1586
1586
/// 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`].
1588
1589
/// Note that calling other methods that materialize mutable references to the slice,
1589
1590
/// or mutable references to specific elements you are planning on accessing through this pointer,
1590
1591
/// as well as writing to those elements, may still invalidate this pointer.
@@ -1621,6 +1622,7 @@ impl<T, A: Allocator> Vec<T, A> {
1621
1622
///
1622
1623
/// [`as_mut_ptr`]: Vec::as_mut_ptr
1623
1624
/// [`as_ptr`]: Vec::as_ptr
1625
+ /// [`as_non_null`]: Vec::as_non_null
1624
1626
#[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
1625
1627
#[ rustc_never_returns_null_ptr]
1626
1628
#[ inline]
@@ -1640,7 +1642,8 @@ impl<T, A: Allocator> Vec<T, A> {
1640
1642
///
1641
1643
/// This method guarantees that for the purpose of the aliasing model, this method
1642
1644
/// 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`].
1644
1647
/// Note that calling other methods that materialize references to the slice,
1645
1648
/// or references to specific elements you are planning on accessing through this pointer,
1646
1649
/// may still invalidate this pointer.
@@ -1680,6 +1683,7 @@ impl<T, A: Allocator> Vec<T, A> {
1680
1683
///
1681
1684
/// [`as_mut_ptr`]: Vec::as_mut_ptr
1682
1685
/// [`as_ptr`]: Vec::as_ptr
1686
+ /// [`as_non_null`]: Vec::as_non_null
1683
1687
#[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
1684
1688
#[ rustc_never_returns_null_ptr]
1685
1689
#[ inline]
@@ -1689,6 +1693,69 @@ impl<T, A: Allocator> Vec<T, A> {
1689
1693
self . buf . ptr ( )
1690
1694
}
1691
1695
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
+
1692
1759
/// Returns a reference to the underlying allocator.
1693
1760
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1694
1761
#[ inline]
0 commit comments