Skip to content

Commit 00f4d06

Browse files
committed
liballoc/{Vec,String}: safety comments for slice methods
1 parent f07b0f9 commit 00f4d06

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

library/alloc/src/string.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,8 @@ impl String {
10791079
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")]
10801080
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
10811081
pub const fn as_str(&self) -> &str {
1082+
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
1083+
// at construction.
10821084
unsafe { str::from_utf8_unchecked(self.vec.as_slice()) }
10831085
}
10841086

@@ -1100,6 +1102,8 @@ impl String {
11001102
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")]
11011103
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
11021104
pub const fn as_mut_str(&mut self) -> &mut str {
1105+
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
1106+
// at construction.
11031107
unsafe { str::from_utf8_unchecked_mut(self.vec.as_mut_slice()) }
11041108
}
11051109

library/alloc/src/vec/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,19 @@ impl<T, A: Allocator> Vec<T, A> {
15511551
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")]
15521552
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
15531553
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.
15541567
unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
15551568
}
15561569

@@ -1570,6 +1583,19 @@ impl<T, A: Allocator> Vec<T, A> {
15701583
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")]
15711584
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
15721585
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.
15731599
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
15741600
}
15751601

0 commit comments

Comments
 (0)