@@ -1252,7 +1252,37 @@ impl<T, A: Allocator> Vec<T, A> {
12521252 #[ inline]
12531253 #[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
12541254 pub fn as_slice ( & self ) -> & [ T ] {
1255- self
1255+ self . as_slice_const ( )
1256+ }
1257+
1258+ /// Extracts a slice containing the entire vector.
1259+ ///
1260+ /// # Examples
1261+ ///
1262+ /// ```
1263+ /// # use std::borrow::Cow;
1264+ /// // `Deref`, `AsRef`, and `as_slice` are not available in `const` contexts, so this doesn't otherwise work.
1265+ /// const fn cow_slice<'c, 's>(c: &Cow<'s, [u8]>) -> &'c [u8]
1266+ /// where 's: 'c {
1267+ /// match c {
1268+ /// Cow::Borrowed(s) => s,
1269+ /// Cow::Owned(s) => s.as_slice_const(),
1270+ /// }
1271+ /// }
1272+ ///
1273+ /// const VEC: Cow<'static, [u8]> = Cow::Owned(Vec::new());
1274+ /// const SLICE: Cow<'static, [u8]> = Cow::Borrowed(b"foo");
1275+ ///
1276+ /// const SLICED_VEC: &'static [u8] = cow_slice(&VEC);
1277+ /// const SLICED_SLICE: &'static [u8] = cow_slice(&SLICE);
1278+ ///
1279+ /// assert_eq!(SLICED_VEC, b"");
1280+ /// assert_eq!(SLICED_SLICE, b"foo");
1281+ /// ```
1282+ #[ inline]
1283+ #[ unstable( feature = "const_vec_string_slice" , issue = "none" ) ]
1284+ pub const fn as_slice_const ( & self ) -> & [ T ] {
1285+ unsafe { slice:: from_raw_parts ( self . as_ptr_const ( ) , self . len ) }
12561286 }
12571287
12581288 /// Extracts a mutable slice of the entire vector.
@@ -1269,7 +1299,7 @@ impl<T, A: Allocator> Vec<T, A> {
12691299 #[ inline]
12701300 #[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
12711301 pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
1272- self
1302+ unsafe { slice :: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
12731303 }
12741304
12751305 /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -1332,6 +1362,68 @@ impl<T, A: Allocator> Vec<T, A> {
13321362 self . buf . ptr ( )
13331363 }
13341364
1365+ /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
1366+ /// valid for zero sized reads if the vector didn't allocate.
1367+ ///
1368+ /// This is a `const` version of [`as_ptr`].
1369+ ///
1370+ /// The caller must ensure that the vector outlives the pointer this
1371+ /// function returns, or else it will end up pointing to garbage.
1372+ /// Modifying the vector may cause its buffer to be reallocated,
1373+ /// which would also make any pointers to it invalid.
1374+ ///
1375+ /// The caller must also ensure that the memory the pointer (non-transitively) points to
1376+ /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
1377+ /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
1378+ ///
1379+ /// This method guarantees that for the purpose of the aliasing model, this method
1380+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
1381+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
1382+ /// Note that calling other methods that materialize mutable references to the slice,
1383+ /// or mutable references to specific elements you are planning on accessing through this pointer,
1384+ /// as well as writing to those elements, may still invalidate this pointer.
1385+ /// See the second example below for how this guarantee can be used.
1386+ ///
1387+ ///
1388+ /// # Examples
1389+ ///
1390+ /// ```
1391+ /// let x = vec![1, 2, 4];
1392+ /// let x_ptr = x.as_ptr_const();
1393+ ///
1394+ /// unsafe {
1395+ /// for i in 0..x.len() {
1396+ /// assert_eq!(*x_ptr.add(i), 1 << i);
1397+ /// }
1398+ /// }
1399+ /// ```
1400+ ///
1401+ /// Due to the aliasing guarantee, the following code is legal:
1402+ ///
1403+ /// ```rust
1404+ /// unsafe {
1405+ /// let mut v = vec![0, 1, 2];
1406+ /// let ptr1 = v.as_ptr_const();
1407+ /// let _ = ptr1.read();
1408+ /// let ptr2 = v.as_mut_ptr().offset(2);
1409+ /// ptr2.write(2);
1410+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`
1411+ /// // because it mutated a different element:
1412+ /// let _ = ptr1.read();
1413+ /// }
1414+ /// ```
1415+ ///
1416+ /// [`as_mut_ptr`]: Vec::as_mut_ptr
1417+ /// [`as_ptr_const`]: Vec::as_ptr
1418+ #[ rustc_never_returns_null_ptr]
1419+ #[ unstable( feature = "const_vec_string_slice" , issue = "none" ) ]
1420+ #[ inline]
1421+ pub const fn as_ptr_const ( & self ) -> * const T {
1422+ // We shadow the slice method of the same name to avoid going through
1423+ // `deref`, which creates an intermediate reference.
1424+ self . buf . ptr_const ( )
1425+ }
1426+
13351427 /// Returns an unsafe mutable pointer to the vector's buffer, or a dangling
13361428 /// raw pointer valid for zero sized reads if the vector didn't allocate.
13371429 ///
@@ -2826,15 +2918,15 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
28262918
28272919 #[ inline]
28282920 fn deref ( & self ) -> & [ T ] {
2829- unsafe { slice :: from_raw_parts ( self . as_ptr ( ) , self . len ) }
2921+ self . as_slice ( )
28302922 }
28312923}
28322924
28332925#[ stable( feature = "rust1" , since = "1.0.0" ) ]
28342926impl < T , A : Allocator > ops:: DerefMut for Vec < T , A > {
28352927 #[ inline]
28362928 fn deref_mut ( & mut self ) -> & mut [ T ] {
2837- unsafe { slice :: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
2929+ self . as_mut_slice ( )
28382930 }
28392931}
28402932
0 commit comments