From 248a9f47996e0b442f1b306b34d42e12b6948a85 Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Tue, 11 Oct 2022 18:33:43 -0700 Subject: [PATCH 1/5] impl String:leak. --- library/alloc/src/string.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 983376a282be5..297ed68ea5269 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -69,7 +69,7 @@ use crate::boxed::Box; use crate::collections::TryReserveError; use crate::str::{self, Chars, Utf8Error}; #[cfg(not(no_global_oom_handling))] -use crate::str::{from_boxed_utf8_unchecked, FromStr}; +use crate::str::{from_boxed_utf8_unchecked, from_utf8_unchecked_mut, FromStr}; use crate::vec::Vec; /// A UTF-8–encoded, growable string. @@ -1849,6 +1849,30 @@ impl String { let slice = self.vec.into_boxed_slice(); unsafe { from_boxed_utf8_unchecked(slice) } } + + /// Consumes and leaks the `String`, returning a mutable reference to the contents, + /// `&'a mut str`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the program's life. Dropping the returned reference will cause a memory + /// leak. + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// let x = String::from("bucket"); + /// let static_ref: &'static mut str = x.leak(); + /// assert_eq!(static_ref, "bucket"); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "string_leak", issue = "102929")] + #[inline] + pub fn leak<'a>(self) -> &'a mut str { + let slice = self.into_bytes().leak(); + unsafe { from_utf8_unchecked_mut(slice) } + } } impl FromUtf8Error { From 4ee922a644d84f4e36696a11f4e3c27e4cd0cf51 Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Tue, 11 Oct 2022 18:53:18 -0700 Subject: [PATCH 2/5] Add feature so doctest works. --- library/alloc/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 7fde8f670a231..e672b28793e32 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -146,6 +146,7 @@ #![feature(slice_ptr_len)] #![feature(slice_range)] #![feature(str_internals)] +#![feature(string_leak)] #![feature(strict_provenance)] #![feature(trusted_len)] #![feature(trusted_random_access)] From 78eaa5ee17890c503843676a5c80117cf8f7f670 Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Tue, 11 Oct 2022 19:27:48 -0700 Subject: [PATCH 3/5] Move feature to doc comment. --- library/alloc/src/lib.rs | 1 - library/alloc/src/string.rs | 10 +++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index e672b28793e32..7fde8f670a231 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -146,7 +146,6 @@ #![feature(slice_ptr_len)] #![feature(slice_range)] #![feature(str_internals)] -#![feature(string_leak)] #![feature(strict_provenance)] #![feature(trusted_len)] #![feature(trusted_random_access)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 297ed68ea5269..5f950dbfb28dd 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1862,9 +1862,13 @@ impl String { /// Simple usage: /// /// ``` - /// let x = String::from("bucket"); - /// let static_ref: &'static mut str = x.leak(); - /// assert_eq!(static_ref, "bucket"); + /// #![feature(string_leak)] + /// + /// pub fn main() { + /// let x = String::from("bucket"); + /// let static_ref: &'static mut str = x.leak(); + /// assert_eq!(static_ref, "bucket"); + /// } /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "string_leak", issue = "102929")] From 3e882e259f1e811ef8c7bd8c065c0d5b8a31ae24 Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Tue, 18 Oct 2022 08:59:05 -0700 Subject: [PATCH 4/5] Revisions. --- library/alloc/src/string.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 5f950dbfb28dd..4fd03a689406a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1853,10 +1853,14 @@ impl String { /// Consumes and leaks the `String`, returning a mutable reference to the contents, /// `&'a mut str`. /// - /// This function is mainly useful for data that lives for the remainder of + /// This is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory /// leak. /// + /// It does not reallocate or shrink the `String`, + /// so the leaked allocation may include unused capacity that is not part + /// of the returned slice. + /// /// # Examples /// /// Simple usage: @@ -1864,17 +1868,15 @@ impl String { /// ``` /// #![feature(string_leak)] /// - /// pub fn main() { - /// let x = String::from("bucket"); - /// let static_ref: &'static mut str = x.leak(); - /// assert_eq!(static_ref, "bucket"); - /// } + /// let x = String::from("bucket"); + /// let static_ref: &'static mut str = x.leak(); + /// assert_eq!(static_ref, "bucket"); /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "string_leak", issue = "102929")] #[inline] - pub fn leak<'a>(self) -> &'a mut str { - let slice = self.into_bytes().leak(); + pub fn leak(self) -> &'static mut str { + let slice = self.vec.leak(); unsafe { from_utf8_unchecked_mut(slice) } } } From 687dd3deac5e46e8db437c737ec04bf7e1ae538f Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Wed, 19 Oct 2022 08:40:43 -0700 Subject: [PATCH 5/5] Allow if no_global_oom_handling, like `Vec::leak`. --- library/alloc/src/string.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 4fd03a689406a..c19a977236582 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1872,7 +1872,6 @@ impl String { /// let static_ref: &'static mut str = x.leak(); /// assert_eq!(static_ref, "bucket"); /// ``` - #[cfg(not(no_global_oom_handling))] #[unstable(feature = "string_leak", issue = "102929")] #[inline] pub fn leak(self) -> &'static mut str {