Auto merge of #125966 - schvv31n:impl_os_string_pathbuf_leak, r=workingjubilee
Implement `os_string_pathbuf_leak` implementation of #125965 ACP: https://github.com/rust-lang/libs-team/issues/389 [ Accepted ]
This commit is contained in:
commit
e484b3efa5
@ -533,6 +533,25 @@ pub fn into_boxed_os_str(self) -> Box<OsStr> {
|
|||||||
unsafe { Box::from_raw(rw) }
|
unsafe { Box::from_raw(rw) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consumes and leaks the `OsString`, returning a mutable reference to the contents,
|
||||||
|
/// `&'a mut OsStr`.
|
||||||
|
///
|
||||||
|
/// The caller has free choice over the returned lifetime, including 'static.
|
||||||
|
/// Indeed, this function is ideally used for data that lives for the remainder of
|
||||||
|
/// the program’s life, as dropping the returned reference will cause a memory leak.
|
||||||
|
///
|
||||||
|
/// It does not reallocate or shrink the `OsString`, so the leaked allocation may include
|
||||||
|
/// unused capacity that is not part of the returned slice. If you want to discard excess
|
||||||
|
/// capacity, call [`into_boxed_os_str`], and then [`Box::leak`] instead.
|
||||||
|
/// However, keep in mind that trimming the capacity may result in a reallocation and copy.
|
||||||
|
///
|
||||||
|
/// [`into_boxed_os_str`]: Self::into_boxed_os_str
|
||||||
|
#[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
|
||||||
|
#[inline]
|
||||||
|
pub fn leak<'a>(self) -> &'a mut OsStr {
|
||||||
|
OsStr::from_inner_mut(self.inner.leak())
|
||||||
|
}
|
||||||
|
|
||||||
/// Part of a hack to make PathBuf::push/pop more efficient.
|
/// Part of a hack to make PathBuf::push/pop more efficient.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
|
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
|
||||||
|
@ -23,6 +23,15 @@ fn test_os_string_clear() {
|
|||||||
assert_eq!(0, os_string.inner.as_inner().len());
|
assert_eq!(0, os_string.inner.as_inner().len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_os_string_leak() {
|
||||||
|
let os_string = OsString::from("have a cake");
|
||||||
|
let (len, cap) = (os_string.len(), os_string.capacity());
|
||||||
|
let leaked = os_string.leak();
|
||||||
|
assert_eq!(leaked.as_encoded_bytes(), b"have a cake");
|
||||||
|
unsafe { drop(String::from_raw_parts(leaked as *mut OsStr as _, len, cap)) }
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_os_string_capacity() {
|
fn test_os_string_capacity() {
|
||||||
let os_string = OsString::with_capacity(0);
|
let os_string = OsString::with_capacity(0);
|
||||||
|
@ -1226,6 +1226,25 @@ pub fn as_path(&self) -> &Path {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consumes and leaks the `PathBuf`, returning a mutable reference to the contents,
|
||||||
|
/// `&'a mut Path`.
|
||||||
|
///
|
||||||
|
/// The caller has free choice over the returned lifetime, including 'static.
|
||||||
|
/// Indeed, this function is ideally used for data that lives for the remainder of
|
||||||
|
/// the program’s life, as dropping the returned reference will cause a memory leak.
|
||||||
|
///
|
||||||
|
/// It does not reallocate or shrink the `PathBuf`, so the leaked allocation may include
|
||||||
|
/// unused capacity that is not part of the returned slice. If you want to discard excess
|
||||||
|
/// capacity, call [`into_boxed_path`], and then [`Box::leak`] instead.
|
||||||
|
/// However, keep in mind that trimming the capacity may result in a reallocation and copy.
|
||||||
|
///
|
||||||
|
/// [`into_boxed_path`]: Self::into_boxed_path
|
||||||
|
#[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
|
||||||
|
#[inline]
|
||||||
|
pub fn leak<'a>(self) -> &'a mut Path {
|
||||||
|
Path::from_inner_mut(self.inner.leak())
|
||||||
|
}
|
||||||
|
|
||||||
/// Extends `self` with `path`.
|
/// Extends `self` with `path`.
|
||||||
///
|
///
|
||||||
/// If `path` is absolute, it replaces the current path.
|
/// If `path` is absolute, it replaces the current path.
|
||||||
|
@ -126,6 +126,16 @@ fn into() {
|
|||||||
assert_eq!(static_cow_path, owned_cow_path);
|
assert_eq!(static_cow_path, owned_cow_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pathbuf_leak() {
|
||||||
|
let string = "/have/a/cake".to_owned();
|
||||||
|
let (len, cap) = (string.len(), string.capacity());
|
||||||
|
let buf = PathBuf::from(string);
|
||||||
|
let leaked = buf.leak();
|
||||||
|
assert_eq!(leaked.as_os_str().as_encoded_bytes(), b"/have/a/cake");
|
||||||
|
unsafe { drop(String::from_raw_parts(leaked.as_mut_os_str() as *mut OsStr as _, len, cap)) }
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn test_decompositions_unix() {
|
pub fn test_decompositions_unix() {
|
||||||
|
@ -176,6 +176,11 @@ pub fn push_slice(&mut self, s: &Slice) {
|
|||||||
self.inner.extend_from_slice(&s.inner)
|
self.inner.extend_from_slice(&s.inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn leak<'a>(self) -> &'a mut Slice {
|
||||||
|
unsafe { mem::transmute(self.inner.leak()) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_box(self) -> Box<Slice> {
|
pub fn into_box(self) -> Box<Slice> {
|
||||||
unsafe { mem::transmute(self.inner.into_boxed_slice()) }
|
unsafe { mem::transmute(self.inner.into_boxed_slice()) }
|
||||||
|
@ -138,6 +138,11 @@ pub fn shrink_to(&mut self, min_capacity: usize) {
|
|||||||
self.inner.shrink_to(min_capacity)
|
self.inner.shrink_to(min_capacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn leak<'a>(self) -> &'a mut Slice {
|
||||||
|
unsafe { mem::transmute(self.inner.leak()) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_box(self) -> Box<Slice> {
|
pub fn into_box(self) -> Box<Slice> {
|
||||||
unsafe { mem::transmute(self.inner.into_box()) }
|
unsafe { mem::transmute(self.inner.into_box()) }
|
||||||
|
@ -325,6 +325,11 @@ pub fn shrink_to(&mut self, min_capacity: usize) {
|
|||||||
self.bytes.shrink_to(min_capacity)
|
self.bytes.shrink_to(min_capacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn leak<'a>(self) -> &'a mut Wtf8 {
|
||||||
|
unsafe { Wtf8::from_mut_bytes_unchecked(self.bytes.leak()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
/// Returns the number of bytes that this string buffer can hold without reallocating.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
|
Loading…
Reference in New Issue
Block a user