Skip to content

Add String::leak #109

@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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions