Description
Proposal
Problem statement
When working in a resource-constrained environment (e.g. Webassembly), it can be useful to leak a small number of String
's to avoid cloning later on.
However, the existing Box::leak(string.into_boxed_str())
may unecessarily reallocate the String
, which is presumably why
Vec::<u8>::leak
exists.
Motivation, use-cases
For example, the following code leaks a String
without reallocation.
// Simulate creation of an <svg>
let string = String::with_capacity(1000);
string.push_str("<svg>");
string.push_str("</svg>");
// New API (never reallocates)
let leaked: &'static mut str = string.leak();
// Hand out to a global memory location, such that consumers of <svg> can access it without cloning.
svgs.write().insert("test", &*leaked);
Solution sketches
impl String {
pub fn leak<'a>(self) -> &'a mut str {
let me = self.into_bytes().leak();
// Safety: Bytes from a [`String`] are valid utf8.
unsafe { std::str::from_utf8_unchecked_mut(me) }
}
}
*note: It may be necessary to bound the allocator's lifetime appropriately, if and when this lands.
Links and related work
As previously emphasized, this change is an extension of Vec::<u8>::leak
.
Right now, StackOverflow answers suggest using
Box::leak(string.into_boxed_str())
, which shrinks the string to fit, possibly causing unnecessary reallocation.
I previously submitted this as an RFC but that was deemed overkill.
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.