Skip to content

Add String::leak #109

Closed
Closed
@finnbear

Description

@finnbear

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions