From 94d8652635efbb85f5dabea296ac07ac98edb6f5 Mon Sep 17 00:00:00 2001 From: lincot Date: Fri, 20 Dec 2024 17:03:45 +0300 Subject: [PATCH] add safety comments to `String::insert_str` and update safety comments in `String::insert` for consistency --- library/alloc/src/string.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 0c50396a9320..6821a6f1298a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -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), @@ -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); } @@ -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); } }