#295 Aug 1, 2026

295. String::leak — A &'static str From Runtime Data, Without the Box Detour

An API demands &'static str, but your string is built at runtime. The old trick was Box::leak(s.into_boxed_str()) — since 1.72, String::leak says what you mean.

You’ve built a name at startup and some API insists on &'static str:

1
2
3
4
5
6
fn set_worker_name(name: &'static str) { /* … */ }

let name = format!("worker-{id}");
set_worker_name(&name);
// error[E0597]: `name` does not
// live long enough

The value will live for the rest of the program — the borrow checker just can’t know that. The classic workaround was leaking through a Box (bite 67):

1
2
let name: &'static str =
    Box::leak(name.into_boxed_str());

String::leak (stable since 1.72) does it in one step, straight off the format!:

1
2
3
let name: &'static str =
    format!("worker-{id}").leak();
set_worker_name(name);

It consumes the String and hands back a &'static mut str — mutable, exclusive, and alive until the process exits (it coerces to plain &'static str on the spot, as above):

1
2
3
4
let m: &'static mut str =
    String::from("abc").leak();
m.make_ascii_uppercase();
assert_eq!(m, "ABC");

Two things to keep in mind. First, the allocation is never freed — that’s the point. Do this for once-per-process values (config, names, interned keys), never in a loop or per-request path. Second, unlike into_boxed_str, which shrinks the buffer to fit, leak leaks the whole allocation, spare capacity included. A String with 4 KB of capacity holding 10 bytes leaks 4 KB. If that matters, call shrink_to_fit() first.

← Previous 294. AssertUnwindSafe — catch_unwind Won't Touch Your &mut Until You Sign the Waiver