@@ -1240,7 +1240,8 @@ impl<T, A: Allocator> Vec<T, A> {
1240
1240
/// ```
1241
1241
#[ inline]
1242
1242
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1243
- pub fn capacity ( & self ) -> usize {
1243
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
1244
+ pub const fn capacity ( & self ) -> usize {
1244
1245
self . buf . capacity ( )
1245
1246
}
1246
1247
@@ -1548,8 +1549,22 @@ impl<T, A: Allocator> Vec<T, A> {
1548
1549
#[ inline]
1549
1550
#[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
1550
1551
#[ cfg_attr( not( test) , rustc_diagnostic_item = "vec_as_slice" ) ]
1551
- pub fn as_slice ( & self ) -> & [ T ] {
1552
- self
1552
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
1553
+ pub const fn as_slice ( & self ) -> & [ T ] {
1554
+ // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
1555
+ // `len` containing properly-initialized `T`s. Data must not be mutated for the returned
1556
+ // lifetime. Further, `len * mem::size_of::<T>` <= `ISIZE::MAX`, and allocation does not
1557
+ // "wrap" through overflowing memory addresses.
1558
+ //
1559
+ // * Vec API guarantees that self.buf:
1560
+ // * contains only properly-initialized items within 0..len
1561
+ // * is aligned, contiguous, and valid for `len` reads
1562
+ // * obeys size and address-wrapping constraints
1563
+ //
1564
+ // * We only construct `&mut` references to `self.buf` through `&mut self` methods; borrow-
1565
+ // check ensures that it is not possible to mutably alias `self.buf` within the
1566
+ // returned lifetime.
1567
+ unsafe { slice:: from_raw_parts ( self . as_ptr ( ) , self . len ) }
1553
1568
}
1554
1569
1555
1570
/// Extracts a mutable slice of the entire vector.
@@ -1566,8 +1581,22 @@ impl<T, A: Allocator> Vec<T, A> {
1566
1581
#[ inline]
1567
1582
#[ stable( feature = "vec_as_slice" , since = "1.7.0" ) ]
1568
1583
#[ cfg_attr( not( test) , rustc_diagnostic_item = "vec_as_mut_slice" ) ]
1569
- pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
1570
- self
1584
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
1585
+ pub const fn as_mut_slice ( & mut self ) -> & mut [ T ] {
1586
+ // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
1587
+ // size `len` containing properly-initialized `T`s. Data must not be accessed through any
1588
+ // other pointer for the returned lifetime. Further, `len * mem::size_of::<T>` <=
1589
+ // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses.
1590
+ //
1591
+ // * Vec API guarantees that self.buf:
1592
+ // * contains only properly-initialized items within 0..len
1593
+ // * is aligned, contiguous, and valid for `len` reads
1594
+ // * obeys size and address-wrapping constraints
1595
+ //
1596
+ // * We only construct references to `self.buf` through `&self` and `&mut self` methods;
1597
+ // borrow-check ensures that it is not possible to construct a reference to `self.buf`
1598
+ // within the returned lifetime.
1599
+ unsafe { slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
1571
1600
}
1572
1601
1573
1602
/// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -1622,9 +1651,10 @@ impl<T, A: Allocator> Vec<T, A> {
1622
1651
/// [`as_mut_ptr`]: Vec::as_mut_ptr
1623
1652
/// [`as_ptr`]: Vec::as_ptr
1624
1653
#[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
1654
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
1625
1655
#[ rustc_never_returns_null_ptr]
1626
1656
#[ inline]
1627
- pub fn as_ptr ( & self ) -> * const T {
1657
+ pub const fn as_ptr ( & self ) -> * const T {
1628
1658
// We shadow the slice method of the same name to avoid going through
1629
1659
// `deref`, which creates an intermediate reference.
1630
1660
self . buf . ptr ( )
@@ -1681,9 +1711,10 @@ impl<T, A: Allocator> Vec<T, A> {
1681
1711
/// [`as_mut_ptr`]: Vec::as_mut_ptr
1682
1712
/// [`as_ptr`]: Vec::as_ptr
1683
1713
#[ stable( feature = "vec_as_ptr" , since = "1.37.0" ) ]
1714
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
1684
1715
#[ rustc_never_returns_null_ptr]
1685
1716
#[ inline]
1686
- pub fn as_mut_ptr ( & mut self ) -> * mut T {
1717
+ pub const fn as_mut_ptr ( & mut self ) -> * mut T {
1687
1718
// We shadow the slice method of the same name to avoid going through
1688
1719
// `deref_mut`, which creates an intermediate reference.
1689
1720
self . buf . ptr ( )
@@ -2561,8 +2592,9 @@ impl<T, A: Allocator> Vec<T, A> {
2561
2592
/// ```
2562
2593
#[ inline]
2563
2594
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2595
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
2564
2596
#[ rustc_confusables( "length" , "size" ) ]
2565
- pub fn len ( & self ) -> usize {
2597
+ pub const fn len ( & self ) -> usize {
2566
2598
self . len
2567
2599
}
2568
2600
@@ -2579,7 +2611,8 @@ impl<T, A: Allocator> Vec<T, A> {
2579
2611
/// ```
2580
2612
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2581
2613
#[ cfg_attr( not( test) , rustc_diagnostic_item = "vec_is_empty" ) ]
2582
- pub fn is_empty ( & self ) -> bool {
2614
+ #[ rustc_const_unstable( feature = "const_vec_string_slice" , issue = "129041" ) ]
2615
+ pub const fn is_empty ( & self ) -> bool {
2583
2616
self . len ( ) == 0
2584
2617
}
2585
2618
@@ -3130,15 +3163,15 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
3130
3163
3131
3164
#[ inline]
3132
3165
fn deref ( & self ) -> & [ T ] {
3133
- unsafe { slice :: from_raw_parts ( self . as_ptr ( ) , self . len ) }
3166
+ self . as_slice ( )
3134
3167
}
3135
3168
}
3136
3169
3137
3170
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3138
3171
impl < T , A : Allocator > ops:: DerefMut for Vec < T , A > {
3139
3172
#[ inline]
3140
3173
fn deref_mut ( & mut self ) -> & mut [ T ] {
3141
- unsafe { slice :: from_raw_parts_mut ( self . as_mut_ptr ( ) , self . len ) }
3174
+ self . as_mut_slice ( )
3142
3175
}
3143
3176
}
3144
3177
0 commit comments