Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove internal PathBuf::as_mut_vec #126885

Merged
merged 4 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
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
16 changes: 13 additions & 3 deletions library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,20 @@ impl OsString {
OsStr::from_inner_mut(self.inner.leak())
}

/// Part of a hack to make PathBuf::push/pop more efficient.
/// Provides plumbing to core `Vec::truncate`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
self.inner.as_mut_vec_for_path_buf()
pub(crate) fn truncate(&mut self, len: usize) {
self.inner.truncate(len);
}

/// Provides plumbing to core `Vec::extend_from_slice`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other);
}
}

Expand Down
31 changes: 13 additions & 18 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,11 +1163,6 @@ pub struct PathBuf {
}

impl PathBuf {
#[inline]
fn as_mut_vec(&mut self) -> &mut Vec<u8> {
self.inner.as_mut_vec_for_path_buf()
}

/// Allocates an empty `PathBuf`.
///
/// # Examples
Expand Down Expand Up @@ -1290,7 +1285,8 @@ impl PathBuf {

fn _push(&mut self, path: &Path) {
// in general, a separator is needed if the rightmost byte is not a separator
let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
let buf = self.inner.as_encoded_bytes();
let mut need_sep = buf.last().map(|c| !is_sep_byte(*c)).unwrap_or(false);

// in the special case of `C:` on Windows, do *not* add a separator
let comps = self.components();
Expand All @@ -1304,7 +1300,7 @@ impl PathBuf {

// absolute `path` replaces `self`
if path.is_absolute() || path.prefix().is_some() {
self.as_mut_vec().truncate(0);
self.inner.truncate(0);

// verbatim paths need . and .. removed
} else if comps.prefix_verbatim() && !path.inner.is_empty() {
Expand Down Expand Up @@ -1349,7 +1345,7 @@ impl PathBuf {
// `path` has a root but no prefix, e.g., `\windows` (Windows only)
} else if path.has_root() {
let prefix_len = self.components().prefix_remaining();
self.as_mut_vec().truncate(prefix_len);
self.inner.truncate(prefix_len);

// `path` is a pure relative path
} else if need_sep {
Expand Down Expand Up @@ -1382,7 +1378,7 @@ impl PathBuf {
pub fn pop(&mut self) -> bool {
match self.parent().map(|p| p.as_u8_slice().len()) {
Some(len) => {
self.as_mut_vec().truncate(len);
self.inner.truncate(len);
true
}
None => false,
Expand Down Expand Up @@ -1510,15 +1506,14 @@ impl PathBuf {
// truncate until right after the file stem
let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
let start = self.inner.as_encoded_bytes().as_ptr().addr();
let v = self.as_mut_vec();
v.truncate(end_file_stem.wrapping_sub(start));
self.inner.truncate(end_file_stem.wrapping_sub(start));

// add the new extension, if any
let new = extension.as_encoded_bytes();
let new = extension;
if !new.is_empty() {
v.reserve_exact(new.len() + 1);
v.push(b'.');
v.extend_from_slice(new);
self.inner.reserve_exact(new.len() + 1);
self.inner.push(OsStr::new("."));
self.inner.push(new);
}

true
Expand Down Expand Up @@ -2645,18 +2640,18 @@ impl Path {
None => {
// Enough capacity for the extension and the dot
let capacity = self_len + extension.len() + 1;
let whole_path = self_bytes.iter();
let whole_path = self_bytes;
(capacity, whole_path)
}
Some(previous_extension) => {
let capacity = self_len + extension.len() - previous_extension.len();
let path_till_dot = self_bytes[..self_len - previous_extension.len()].iter();
let path_till_dot = &self_bytes[..self_len - previous_extension.len()];
(capacity, path_till_dot)
}
};

let mut new_path = PathBuf::with_capacity(new_capacity);
new_path.as_mut_vec().extend(slice_to_copy);
new_path.inner.extend_from_slice(slice_to_copy);
new_path.set_extension(extension);
new_path
}
Expand Down
16 changes: 13 additions & 3 deletions library/std/src/sys/os_str/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,20 @@ impl Buf {
self.as_slice().into_rc()
}

/// Part of a hack to make PathBuf::push/pop more efficient.
/// Provides plumbing to core `Vec::truncate`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
&mut self.inner
pub(crate) fn truncate(&mut self, len: usize) {
self.inner.truncate(len);
}

/// Provides plumbing to core `Vec::extend_from_slice`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other);
}
}

Expand Down
16 changes: 13 additions & 3 deletions library/std/src/sys/os_str/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,20 @@ impl Buf {
self.as_slice().into_rc()
}

/// Part of a hack to make PathBuf::push/pop more efficient.
/// Provides plumbing to core `Vec::truncate`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
self.inner.as_mut_vec_for_path_buf()
pub(crate) fn truncate(&mut self, len: usize) {
self.inner.truncate(len);
}
Borgerr marked this conversation as resolved.
Show resolved Hide resolved

/// Provides plumbing to core `Vec::extend_from_slice`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
self.inner.extend_from_slice(other);
}
}

Expand Down
12 changes: 6 additions & 6 deletions library/std/src/sys_common/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,13 @@ impl Wtf8Buf {
Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false }
}

/// Part of a hack to make PathBuf::push/pop more efficient.
/// Provides plumbing to core `Vec::extend_from_slice`.
/// More well behaving alternative to allowing outer types
/// full mutable access to the core `Vec`.
#[inline]
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
// FIXME: this function should not even exist, as it implies violating Wtf8Buf invariants
// For now, simply assume that is about to happen.
self.is_known_utf8 = false;
&mut self.bytes
pub(crate) fn extend_from_slice(&mut self, other: &[u8]) {
self.bytes.extend_from_slice(other);
Borgerr marked this conversation as resolved.
Show resolved Hide resolved
self.is_known_utf8 = self.is_known_utf8 || self.next_surrogate(0).is_none();
}
}

Expand Down
Loading