Skip to content

Commit c47978a

Browse files
committed
PathBuf: replace transmuting by accessor functions
1 parent 5ff8fbb commit c47978a

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

library/std/src/ffi/os_str.rs

+6
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,12 @@ impl OsString {
532532
let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
533533
unsafe { Box::from_raw(rw) }
534534
}
535+
536+
/// Part of a hack to make PathBuf::push/pop more efficient.
537+
#[inline]
538+
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
539+
self.inner.as_mut_vec_for_path_buf()
540+
}
535541
}
536542

537543
#[stable(feature = "rust1", since = "1.0.0")]

library/std/src/path.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1158,20 +1158,14 @@ impl FusedIterator for Ancestors<'_> {}
11581158
/// Which method works best depends on what kind of situation you're in.
11591159
#[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
11601160
#[stable(feature = "rust1", since = "1.0.0")]
1161-
// `PathBuf::as_mut_vec` current implementation relies
1162-
// on `PathBuf` being layout-compatible with `Vec<u8>`.
1163-
// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
1164-
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
1165-
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
1166-
#[cfg_attr(not(doc), repr(transparent))]
11671161
pub struct PathBuf {
11681162
inner: OsString,
11691163
}
11701164

11711165
impl PathBuf {
11721166
#[inline]
11731167
fn as_mut_vec(&mut self) -> &mut Vec<u8> {
1174-
unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
1168+
self.inner.as_mut_vec_for_path_buf()
11751169
}
11761170

11771171
/// Allocates an empty `PathBuf`.

library/std/src/sys/os_str/bytes.rs

+6
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ impl Buf {
198198
pub fn into_rc(&self) -> Rc<Slice> {
199199
self.as_slice().into_rc()
200200
}
201+
202+
/// Part of a hack to make PathBuf::push/pop more efficient.
203+
#[inline]
204+
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
205+
&mut self.inner
206+
}
201207
}
202208

203209
impl Slice {

library/std/src/sys/os_str/wtf8.rs

+6
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ impl Buf {
158158
pub fn into_rc(&self) -> Rc<Slice> {
159159
self.as_slice().into_rc()
160160
}
161+
162+
/// Part of a hack to make PathBuf::push/pop more efficient.
163+
#[inline]
164+
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
165+
self.inner.as_mut_vec_for_path_buf()
166+
}
161167
}
162168

163169
impl Slice {

library/std/src/sys_common/wtf8.rs

+6
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,12 @@ impl Wtf8Buf {
468468
let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
469469
Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false }
470470
}
471+
472+
/// Part of a hack to make PathBuf::push/pop more efficient.
473+
#[inline]
474+
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
475+
&mut self.bytes
476+
}
471477
}
472478

473479
/// Creates a new WTF-8 string from an iterator of code points.

0 commit comments

Comments
 (0)