From 2155c6c47761391673a2794430dc78436c25bbf8 Mon Sep 17 00:00:00 2001 From: ash <97464181+Borgerr@users.noreply.github.com> Date: Sat, 22 Jun 2024 18:53:31 -0600 Subject: [PATCH 1/4] #126333 remove `PathBuf::as_mut_vec` reference at top of `PathBuf::_push` --- library/std/src/path.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 72073d1328023..13947122dcadc 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1290,7 +1290,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(); From b08cd69684e4b121399b3ea0f9ee6cc4a51cad07 Mon Sep 17 00:00:00 2001 From: ash <97464181+Borgerr@users.noreply.github.com> Date: Sun, 23 Jun 2024 08:36:23 -0600 Subject: [PATCH 2/4] inner truncate methods for UEFI platforms --- library/std/src/ffi/os_str.rs | 5 +++++ library/std/src/path.rs | 6 +++--- library/std/src/sys/os_str/bytes.rs | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index f6b9de26c1c4d..318fe205e0faf 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -557,6 +557,11 @@ impl OsString { pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { self.inner.as_mut_vec_for_path_buf() } + + #[inline] + pub(crate) fn truncate(&mut self, len: usize) { + self.inner.truncate(len); + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 13947122dcadc..fb7476a3b267a 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1305,7 +1305,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() { @@ -1350,7 +1350,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 { @@ -1383,7 +1383,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, diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index f7c6b0877aa62..e494f7d1dea10 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -207,6 +207,11 @@ impl Buf { pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { &mut self.inner } + + #[inline] + pub(crate) fn truncate(&mut self, len: usize) { + self.inner.truncate(len); + } } impl Slice { From 7e187e8e4b0a12b9adc0d24dc30dffde6ceaba4a Mon Sep 17 00:00:00 2001 From: ash <97464181+Borgerr@users.noreply.github.com> Date: Sun, 23 Jun 2024 17:24:59 -0600 Subject: [PATCH 3/4] remove references to `PathBuf::as_mut_vec` in `PathBuf::_set_extension` --- library/std/src/path.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index fb7476a3b267a..fb488ae94a1e6 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1511,15 +1511,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 From aa46a3368eb017eba41bfab956c7787d46c09935 Mon Sep 17 00:00:00 2001 From: ash <97464181+Borgerr@users.noreply.github.com> Date: Tue, 25 Jun 2024 07:34:35 -0600 Subject: [PATCH 4/4] `PathBuf::as_mut_vec` removed and verified for UEFI and Windows platforms #126333 --- library/std/src/ffi/os_str.rs | 15 ++++++++++----- library/std/src/path.rs | 11 +++-------- library/std/src/sys/os_str/bytes.rs | 15 ++++++++++----- library/std/src/sys/os_str/wtf8.rs | 16 +++++++++++++--- library/std/src/sys_common/wtf8.rs | 12 ++++++------ 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 318fe205e0faf..4a417c84a30a5 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -552,15 +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 { - 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 truncate(&mut self, len: usize) { - self.inner.truncate(len); + pub(crate) fn extend_from_slice(&mut self, other: &[u8]) { + self.inner.extend_from_slice(other); } } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index fb488ae94a1e6..caae8f924d2b1 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1163,11 +1163,6 @@ pub struct PathBuf { } impl PathBuf { - #[inline] - fn as_mut_vec(&mut self) -> &mut Vec { - self.inner.as_mut_vec_for_path_buf() - } - /// Allocates an empty `PathBuf`. /// /// # Examples @@ -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 } diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index e494f7d1dea10..2a7477e3afc20 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -202,15 +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 { - &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 truncate(&mut self, len: usize) { - self.inner.truncate(len); + pub(crate) fn extend_from_slice(&mut self, other: &[u8]) { + self.inner.extend_from_slice(other); } } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 96690f8c44e9c..edb923a47501c 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -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 { - 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); } } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 84128a4b595f7..708f62f476e73 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -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 { - // 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); + self.is_known_utf8 = self.is_known_utf8 || self.next_surrogate(0).is_none(); } }