File tree Expand file tree Collapse file tree 7 files changed +72
-0
lines changed Expand file tree Collapse file tree 7 files changed +72
-0
lines changed Original file line number Diff line number Diff line change @@ -533,6 +533,25 @@ impl OsString {
533
533
unsafe { Box::from_raw(rw) }
534
534
}
535
535
536
+ /// Consumes and leaks the `OsString`, returning a mutable reference to the contents,
537
+ /// `&'a mut OsStr`.
538
+ ///
539
+ /// The caller has free choice over the returned lifetime, including 'static.
540
+ /// Indeed, this function is ideally used for data that lives for the remainder of
541
+ /// the program’s life, as dropping the returned reference will cause a memory leak.
542
+ ///
543
+ /// It does not reallocate or shrink the `OsString`, so the leaked allocation may include
544
+ /// unused capacity that is not part of the returned slice. If you want to discard excess
545
+ /// capacity, call [`into_boxed_os_str`], and then [`Box::leak`] instead.
546
+ /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
547
+ ///
548
+ /// [`into_boxed_os_str`]: Self::into_boxed_os_str
549
+ #[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
550
+ #[inline]
551
+ pub fn leak<'a>(self) -> &'a mut OsStr {
552
+ OsStr::from_inner_mut(self.inner.leak())
553
+ }
554
+
536
555
/// Part of a hack to make PathBuf::push/pop more efficient.
537
556
#[inline]
538
557
pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec<u8> {
Original file line number Diff line number Diff line change @@ -23,6 +23,15 @@ fn test_os_string_clear() {
23
23
assert_eq!(0, os_string.inner.as_inner().len());
24
24
}
25
25
26
+ #[test]
27
+ fn test_os_string_leak() {
28
+ let os_string = OsString::from("have a cake");
29
+ let (len, cap) = (os_string.len(), os_string.capacity());
30
+ let leaked = os_string.leak();
31
+ assert_eq!(leaked.as_encoded_bytes(), b"have a cake");
32
+ unsafe { drop(String::from_raw_parts(leaked as *mut OsStr as _, len, cap)) }
33
+ }
34
+
26
35
#[test]
27
36
fn test_os_string_capacity() {
28
37
let os_string = OsString::with_capacity(0);
Original file line number Diff line number Diff line change @@ -1226,6 +1226,25 @@ impl PathBuf {
1226
1226
self
1227
1227
}
1228
1228
1229
+ /// Consumes and leaks the `PathBuf`, returning a mutable reference to the contents,
1230
+ /// `&'a mut Path`.
1231
+ ///
1232
+ /// The caller has free choice over the returned lifetime, including 'static.
1233
+ /// Indeed, this function is ideally used for data that lives for the remainder of
1234
+ /// the program’s life, as dropping the returned reference will cause a memory leak.
1235
+ ///
1236
+ /// It does not reallocate or shrink the `PathBuf`, so the leaked allocation may include
1237
+ /// unused capacity that is not part of the returned slice. If you want to discard excess
1238
+ /// capacity, call [`into_boxed_path`], and then [`Box::leak`] instead.
1239
+ /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
1240
+ ///
1241
+ /// [`into_boxed_path`]: Self::into_boxed_path
1242
+ #[unstable(feature = "os_string_pathbuf_leak", issue = "125965")]
1243
+ #[inline]
1244
+ pub fn leak<'a>(self) -> &'a mut Path {
1245
+ Path::from_inner_mut(self.inner.leak())
1246
+ }
1247
+
1229
1248
/// Extends `self` with `path`.
1230
1249
///
1231
1250
/// If `path` is absolute, it replaces the current path.
Original file line number Diff line number Diff line change @@ -126,6 +126,16 @@ fn into() {
126
126
assert_eq!(static_cow_path, owned_cow_path);
127
127
}
128
128
129
+ #[test]
130
+ fn test_pathbuf_leak() {
131
+ let string = "/have/a/cake".to_owned();
132
+ let (len, cap) = (string.len(), string.capacity());
133
+ let buf = PathBuf::from(string);
134
+ let leaked = buf.leak();
135
+ assert_eq!(leaked.as_os_str().as_encoded_bytes(), b"/have/a/cake");
136
+ unsafe { drop(String::from_raw_parts(leaked.as_mut_os_str() as *mut OsStr as _, len, cap)) }
137
+ }
138
+
129
139
#[test]
130
140
#[cfg(unix)]
131
141
pub fn test_decompositions_unix() {
Original file line number Diff line number Diff line change @@ -176,6 +176,11 @@ impl Buf {
176
176
self.inner.extend_from_slice(&s.inner)
177
177
}
178
178
179
+ #[inline]
180
+ pub fn leak<'a>(self) -> &'a mut Slice {
181
+ unsafe { mem::transmute(self.inner.leak()) }
182
+ }
183
+
179
184
#[inline]
180
185
pub fn into_box(self) -> Box<Slice> {
181
186
unsafe { mem::transmute(self.inner.into_boxed_slice()) }
Original file line number Diff line number Diff line change @@ -138,6 +138,11 @@ impl Buf {
138
138
self.inner.shrink_to(min_capacity)
139
139
}
140
140
141
+ #[inline]
142
+ pub fn leak<'a>(self) -> &'a mut Slice {
143
+ unsafe { mem::transmute(self.inner.leak()) }
144
+ }
145
+
141
146
#[inline]
142
147
pub fn into_box(self) -> Box<Slice> {
143
148
unsafe { mem::transmute(self.inner.into_box()) }
Original file line number Diff line number Diff line change @@ -325,6 +325,11 @@ impl Wtf8Buf {
325
325
self.bytes.shrink_to(min_capacity)
326
326
}
327
327
328
+ #[inline]
329
+ pub fn leak<'a>(self) -> &'a mut Wtf8 {
330
+ unsafe { Wtf8::from_mut_bytes_unchecked(self.bytes.leak()) }
331
+ }
332
+
328
333
/// Returns the number of bytes that this string buffer can hold without reallocating.
329
334
#[inline]
330
335
pub fn capacity(&self) -> usize {
You can’t perform that action at this time.
0 commit comments