Make internal OsString::truncate and extend_from_slice unsafe

Communicate the safety invariants of these methods with `unsafe fn`
rather than privacy.
This commit is contained in:
Thalia Archibald
2025-04-11 02:52:17 -07:00
parent 9bfa31f632
commit 7cb357a36b
4 changed files with 53 additions and 23 deletions

View File

@@ -582,15 +582,25 @@ impl OsString {
#[unstable(feature = "os_string_truncate", issue = "133262")] #[unstable(feature = "os_string_truncate", issue = "133262")]
pub fn truncate(&mut self, len: usize) { pub fn truncate(&mut self, len: usize) {
self.as_os_str().inner.check_public_boundary(len); self.as_os_str().inner.check_public_boundary(len);
self.inner.truncate(len); // SAFETY: The length was just checked to be at a valid boundary.
unsafe { self.inner.truncate_unchecked(len) };
} }
/// Provides plumbing to core `Vec::extend_from_slice`. /// Provides plumbing to `Vec::extend_from_slice` without giving full
/// More well behaving alternative to allowing outer types /// mutable access to the `Vec`.
/// full mutable access to the core `Vec`. ///
/// # Safety
///
/// The slice must be valid for the platform encoding (as described in
/// [`OsStr::from_encoded_bytes_unchecked`]).
///
/// This bypasses the encoding-dependent surrogate joining, so `self` must
/// not end with a leading surrogate half and `other` must not start with
/// with a trailing surrogate half.
#[inline] #[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) { pub(crate) unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other); // SAFETY: Guaranteed by caller.
unsafe { self.inner.extend_from_slice_unchecked(other) };
} }
} }

View File

@@ -2759,7 +2759,8 @@ impl Path {
}; };
let mut new_path = PathBuf::with_capacity(new_capacity); let mut new_path = PathBuf::with_capacity(new_capacity);
new_path.inner.extend_from_slice(slice_to_copy); // SAFETY: The path is empty, so cannot have surrogate halves.
unsafe { new_path.inner.extend_from_slice_unchecked(slice_to_copy) };
new_path.set_extension(extension); new_path.set_extension(extension);
new_path new_path
} }

View File

@@ -216,19 +216,26 @@ impl Buf {
self.as_slice().into_rc() self.as_slice().into_rc()
} }
/// Provides plumbing to core `Vec::truncate`. /// Provides plumbing to `Vec::truncate` without giving full mutable access
/// More well behaving alternative to allowing outer types /// to the `Vec`.
/// full mutable access to the core `Vec`. ///
/// # Safety
///
/// The length must be at an `OsStr` boundary, according to
/// `Slice::check_public_boundary`.
#[inline] #[inline]
pub(crate) fn truncate(&mut self, len: usize) { pub unsafe fn truncate_unchecked(&mut self, len: usize) {
self.inner.truncate(len); self.inner.truncate(len);
} }
/// Provides plumbing to core `Vec::extend_from_slice`. /// Provides plumbing to `Vec::extend_from_slice` without giving full
/// More well behaving alternative to allowing outer types /// mutable access to the `Vec`.
/// full mutable access to the core `Vec`. ///
/// # Safety
///
/// This encoding has no safety requirements.
#[inline] #[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) { pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other); self.inner.extend_from_slice(other);
} }
} }

View File

@@ -195,19 +195,31 @@ impl Buf {
self.as_slice().into_rc() self.as_slice().into_rc()
} }
/// Provides plumbing to core `Vec::truncate`. /// Provides plumbing to `Vec::truncate` without giving full mutable access
/// More well behaving alternative to allowing outer types /// to the `Vec`.
/// full mutable access to the core `Vec`. ///
/// # Safety
///
/// The length must be at an `OsStr` boundary, according to
/// `Slice::check_public_boundary`.
#[inline] #[inline]
pub(crate) fn truncate(&mut self, len: usize) { pub unsafe fn truncate_unchecked(&mut self, len: usize) {
self.inner.truncate(len); self.inner.truncate(len);
} }
/// Provides plumbing to core `Vec::extend_from_slice`. /// Provides plumbing to `Vec::extend_from_slice` without giving full
/// More well behaving alternative to allowing outer types /// mutable access to the `Vec`.
/// full mutable access to the core `Vec`. ///
/// # Safety
///
/// The slice must be valid for the platform encoding (as described in
/// [`Slice::from_encoded_bytes_unchecked`]).
///
/// This bypasses the WTF-8 surrogate joining, so `self` must not end with a
/// leading surrogate half and `other` must not start with with a trailing
/// surrogate half.
#[inline] #[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) { pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other); self.inner.extend_from_slice(other);
} }
} }