Skip to content

Commit

Permalink
add safety comments to String::insert_str
Browse files Browse the repository at this point in the history
and update safety comments in `String::insert` for consistency
  • Loading branch information
lincot committed Dec 20, 2024
1 parent d83dbb5 commit 94d8652
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1726,8 +1726,9 @@ impl String {
let ch_len = ch.len_utf8();
self.reserve(ch_len);

// SAFETY: Shift data `ch_len` bytes to the right,
// capacity was just reserved for at least that many bytes.
// SAFETY: Move the bytes starting from `idx` to their new location `ch_len`
// bytes ahead. This is safe because sufficient capacity was reserved, and `idx`
// is a char boundary.
unsafe {
ptr::copy(
self.vec.as_ptr().add(idx),
Expand All @@ -1736,13 +1737,13 @@ impl String {
);
}

// SAFETY: Encode the character into the space left after the shift
// if `idx != len`, or into the uninitialized spare capacity otherwise.
// SAFETY: Encode the character into the vacated region if `idx != len`,
// or into the uninitialized spare capacity otherwise.
unsafe {
core::char::encode_utf8_raw_unchecked(ch as u32, self.vec.as_mut_ptr().add(idx));
}

// SAFETY: `ch_len` initialized bytes have been added.
// SAFETY: Update the length to include the newly added bytes.
unsafe {
self.vec.set_len(len + ch_len);
}
Expand Down Expand Up @@ -1778,9 +1779,26 @@ impl String {
let amt = string.len();
self.reserve(amt);

// SAFETY: Move the bytes starting from `idx` to their new location `amt` bytes
// ahead. This is safe because sufficient capacity was just reserved, and `idx`
// is a char boundary.
unsafe {
ptr::copy(
self.vec.as_ptr().add(idx),
self.vec.as_mut_ptr().add(idx + amt),
len - idx,
);
}

// SAFETY: Copy the new string slice into the vacated region if `idx != len`,
// or into the uninitialized spare capacity otherwise. The borrow checker
// ensures that the source and destination do not overlap.
unsafe {
ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
ptr::copy_nonoverlapping(string.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
}

// SAFETY: Update the length to include the newly added bytes.
unsafe {
self.vec.set_len(len + amt);
}
}
Expand Down

0 comments on commit 94d8652

Please sign in to comment.