Rollup merge of #140159 - thaliaarchi:pathbuf-extension, r=workingjubilee
Avoid redundant WTF-8 checks in `PathBuf` Eliminate checks for WTF-8 boundaries in `PathBuf::set_extension` and `add_extension`, where joining WTF-8 surrogate halves is impossible. Don't convert the `str` to `OsStr`, because `OsString::push` specializes to skip the joining when given strings. To assist in this, mark the internal methods `OsString::truncate` and `extend_from_slice` as `unsafe` to communicate their safety invariants better than with module privacy. Similar to #137777. cc `@joboet` `@ChrisDenton`
This commit is contained in:
@@ -1529,11 +1529,13 @@ impl PathBuf {
|
||||
self.inner.truncate(end_file_stem.wrapping_sub(start));
|
||||
|
||||
// add the new extension, if any
|
||||
let new = extension;
|
||||
let new = extension.as_encoded_bytes();
|
||||
if !new.is_empty() {
|
||||
self.inner.reserve_exact(new.len() + 1);
|
||||
self.inner.push(OsStr::new("."));
|
||||
self.inner.push(new);
|
||||
self.inner.push(".");
|
||||
// SAFETY: Since a UTF-8 string was just pushed, it is not possible
|
||||
// for the buffer to end with a surrogate half.
|
||||
unsafe { self.inner.extend_from_slice_unchecked(new) };
|
||||
}
|
||||
|
||||
true
|
||||
@@ -1597,7 +1599,7 @@ impl PathBuf {
|
||||
Some(f) => f.as_encoded_bytes(),
|
||||
};
|
||||
|
||||
let new = extension;
|
||||
let new = extension.as_encoded_bytes();
|
||||
if !new.is_empty() {
|
||||
// truncate until right after the file name
|
||||
// this is necessary for trimming the trailing slash
|
||||
@@ -1607,8 +1609,10 @@ impl PathBuf {
|
||||
|
||||
// append the new extension
|
||||
self.inner.reserve_exact(new.len() + 1);
|
||||
self.inner.push(OsStr::new("."));
|
||||
self.inner.push(new);
|
||||
self.inner.push(".");
|
||||
// SAFETY: Since a UTF-8 string was just pushed, it is not possible
|
||||
// for the buffer to end with a surrogate half.
|
||||
unsafe { self.inner.extend_from_slice_unchecked(new) };
|
||||
}
|
||||
|
||||
true
|
||||
@@ -2769,7 +2773,8 @@ impl Path {
|
||||
};
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user