Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ impl String {
let (chunks, []) = v.as_chunks::<2>() else {
return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes });
};
// ignore-tidy-undocumented-unsafe
// SAFETY: The aligned part of `v` can be transmuted into a valid u16 slice.
match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16(v),
_ => {
Expand Down Expand Up @@ -838,7 +838,7 @@ impl String {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "str_from_utf16_endian", since = "1.98.0")]
pub fn from_utf16le_lossy(v: &[u8]) -> String {
// ignore-tidy-undocumented-unsafe
// SAFETY: The aligned part of `v` can be transmuted into a valid u16 slice.
match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16_lossy(v),
(true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
Expand Down Expand Up @@ -877,7 +877,7 @@ impl String {
let (chunks, []) = v.as_chunks::<2>() else {
return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes });
};
// ignore-tidy-undocumented-unsafe
// SAFETY: The aligned part of `v` can be transmuted into a valid u16 slice.
match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16(v),
_ => {
Expand Down Expand Up @@ -913,7 +913,7 @@ impl String {
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "str_from_utf16_endian", since = "1.98.0")]
pub fn from_utf16be_lossy(v: &[u8]) -> String {
// ignore-tidy-undocumented-unsafe
// SAFETY: The aligned part of `v` can be transmuted into a valid u16 slice.
match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16_lossy(v),
(true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
Expand Down Expand Up @@ -1143,7 +1143,8 @@ impl String {
let additional: Saturating<usize> = slice.iter().map(|x| Saturating(x.len())).sum();
self.reserve(additional.0);
let (ptr, len, cap) = core::mem::take(self).into_raw_parts();
// ignore-tidy-undocumented-unsafe
// SAFETY: `self` have reserved enough space for strs in `slice`, and we are copying from valid UTF-8 slices.
// Therefore all unsafe operations are safe.
unsafe {
let mut dst = ptr.add(len);
for new in slice {
Expand Down Expand Up @@ -1532,7 +1533,7 @@ impl String {
pub fn pop(&mut self) -> Option<char> {
let ch = self.chars().rev().next()?;
let newlen = self.len() - ch.len_utf8();
// ignore-tidy-undocumented-unsafe
// SAFETY: `newlen` is less than old length.
unsafe {
self.vec.set_len(newlen);
}
Expand Down Expand Up @@ -1571,7 +1572,11 @@ impl String {

let next = idx + ch.len_utf8();
let len = self.len();
// ignore-tidy-undocumented-unsafe
// SAFETY:
// * Since `next` is not bigger than `len`, `self.vec.as_ptr().add(next)`
// is valid for reads and `self.vec.as_mut_ptr().add(idx)` is valid for writes.
// Both pointers are valid for `len - next` bytes.
// * new length is less than old length.
unsafe {
ptr::copy(self.vec.as_ptr().add(next), self.vec.as_mut_ptr().add(idx), len - next);
self.vec.set_len(len - (next - idx));
Expand Down Expand Up @@ -1645,7 +1650,7 @@ impl String {
len += count;
}

// ignore-tidy-undocumented-unsafe
// SAFETY: `len` is less than or equal to the original length of the string.
unsafe {
self.vec.set_len(len);
}
Expand Down Expand Up @@ -1954,7 +1959,7 @@ impl String {
pub fn split_off(&mut self, at: usize) -> String {
assert!(self.is_char_boundary(at));
let other = self.vec.split_off(at);
// ignore-tidy-undocumented-unsafe
// SAFETY: `other` contains only valid UTF-8 because `at` is on a `UTF-8` code point boundary.
unsafe { String::from_utf8_unchecked(other) }
}

Expand Down Expand Up @@ -2224,7 +2229,7 @@ impl String {
#[inline]
pub fn into_boxed_str(self) -> Box<str> {
let slice = self.vec.into_boxed_slice();
// ignore-tidy-undocumented-unsafe
// SAFETY: `slice` contains only valid UTF-8 because `String` is guaranteed to be valid UTF-8.
unsafe { from_boxed_utf8_unchecked(slice) }
}

Expand Down Expand Up @@ -2256,7 +2261,7 @@ impl String {
#[inline]
pub fn leak<'a>(self) -> &'a mut str {
let slice = self.vec.leak();
// ignore-tidy-undocumented-unsafe
// SAFETY: `slice` contains only valid UTF-8 because `String` is guaranteed to be valid UTF-8.
unsafe { from_utf8_unchecked_mut(slice) }
}
}
Expand Down Expand Up @@ -3586,14 +3591,12 @@ unsafe impl Send for Drain<'_> {}
#[stable(feature = "drain", since = "1.6.0")]
impl Drop for Drain<'_> {
fn drop(&mut self) {
// ignore-tidy-undocumented-unsafe
unsafe {
// Use Vec::drain. "Reaffirm" the bounds checks to avoid
// panic code being inserted again.
let self_vec = (*self.string).as_mut_vec();
if self.start <= self.end && self.end <= self_vec.len() {
self_vec.drain(self.start..self.end);
}
// Use Vec::drain. "Reaffirm" the bounds checks to avoid
// panic code being inserted again.
// SAFETY: We only use the returned Vec to call drain.
let self_vec = unsafe { &mut *(*self.string).as_mut_vec() };
if self.start <= self.end && self.end <= self_vec.len() {
self_vec.drain(self.start..self.end);
}
}
}
Expand Down
Loading