17.5The 'static lifetime
One lifetime has a name and you've used it since chapter 5: 'static, the lifetime of string literals. It means "valid for the entire duration of the program," the longest possible lifetime. This short lesson explains what 'static is, why string literals have it, and, most importantly, warns against the common beginner trap of adding 'static to make a borrow-checker error go away. The annotation is almost never the right fix, and knowing why saves you a frustrating detour.
What 'static means
'static is the lifetime that lasts the whole program, from start to finish. A reference with the 'static lifetime is guaranteed valid forever, because the data it points at lives forever. The clearest example is a string literal, which you've written since lesson 1.1:
fn main() {
let s: &'static str = "I live for the whole program";
println!("{s}");
}I live for the whole program
Every string literal has type &'static str. Lesson 5.4 noted that a literal is a &str, and lesson 9.7 added that it's specifically &'static str; here's why. The text of a string literal is baked directly into the compiled program's binary, so it exists for as long as the program runs. A reference to it can therefore be valid for the entire program, which is exactly what 'static denotes. You've been creating 'static references every time you wrote "hello", the type annotation was just elided.
This is also why a function can return a string literal without any lifetime trouble: fn greeting() -> &'static str { "hello" } compiles cleanly, because the returned reference points at data that lives forever, so there's no value it could outlive.
Key insight
'static is the lifetime of data that lives for the whole program. String literals have it because their bytes are embedded in the binary. It's the one concrete, nameable lifetime you'll write (the 'a in earlier lessons was a variable standing for "some lifetime"; 'static names a specific one, the longest). A &'static T is a promise that the reference will be valid no matter how long the program runs.
The 'static trap
Here's the warning. When you hit a borrow-checker error like "does not live long enough" (lesson 17.2), the compiler sometimes mentions 'static, and a tempting "fix" is to add 'static bounds until the error disappears. This is almost always wrong, and understanding why is the point of the lesson.
Adding 'static doesn't make data live longer (no annotation does, lesson 17.2); it demands that the data already lives for the whole program. So slapping 'static on a reference to a local value doesn't satisfy the borrow checker, it changes the error to "this local isn't 'static," because the local genuinely isn't. You've just told the compiler to require something even stronger, which the local still can't provide. The error moves; the problem doesn't.
fn main() {
let name = String::from("Ada");
let r: &'static str = &name; // refused: name isn't 'static
println!("{r}");
}error[E0597]: `name` does not live long enough
--> src/main.rs:3:27
|
2 | let name = String::from("Ada");
| ---- binding `name` declared here
3 | let r: &'static str = &name;
| ------------ ^^^^^ borrowed value does not live long enough
| |
| type annotation requires that `name` is borrowed for `'static`
The annotation requires name to be 'static, and name is a local that's dropped at the end of main, so it can't be. The 'static made things worse, not better.
What to do instead
When you hit "does not live long enough," the real fixes are about actual lifetimes, not annotations:
Own the data. The most common fix: instead of borrowing, use an owned String or Vec (the lesson 10.8 and 17.3 advice). An owned value carries no lifetime constraint, so the whole class of "doesn't live long enough" errors evaporates. This solves the large majority of cases.
Restructure so the data outlives the borrow. Move the owner so it lives long enough, reorder so the borrow ends before the owner is dropped (the "borrows end at last use" idea from chapter 9), or pass ownership in rather than borrowing.
Use 'static only when the data genuinely is 'static, like a string literal or a true constant (lesson 5.1). 'static is a description that fits literals and constants; it's not a tool for extending the life of locals.
Best practice
Treat 'static as a description of data that truly lives forever (literals, constants), never as a fix for a borrow error. If the compiler says a value doesn't live long enough, reach for owned data (String, Vec) or restructure so the value outlives its borrow, don't add 'static. The presence of 'static in your own code, outside literal and constant contexts, is usually a smell worth a second look.
Quiz time
Question #1
What does the 'static lifetime mean, and why do string literals have it?
Show solution
'static means the reference is valid for the entire duration of the program (the longest possible lifetime). String literals have it because their bytes are embedded directly in the compiled binary, so they exist for as long as the program runs, and a reference to them can be valid the whole time. Every "..." literal has type &'static str.
Question #2
Why doesn't adding &'static to a reference to a local variable fix a "does not live long enough" error?
Show solution
Because 'static doesn't extend a value's life; it requires the value to already live for the whole program. A local variable is dropped at the end of its scope, so it isn't 'static, and demanding 'static just produces a new error ("this local isn't 'static"). The annotation asks for something even stronger than before, which the local still can't satisfy.
Question #3
You get "does not live long enough" on a function returning a reference to a String it created locally. What are the right fixes?
Show solution
Return the owned String itself instead of a reference (the data the caller is given then lives as long as they keep it), or restructure so the data is owned by the caller and passed in. The fix is to deal with real ownership/lifetimes, not to add 'static, which would just demand the impossible of a local value. Owning the data is the usual answer (lessons 10.8, 17.3).
That completes lifetimes: what they are, writing them on functions and structs, the elision rules that usually spare you, and 'static. The summary is next, and then chapter 18 returns to practical ground with the collections you'll use in every real program, Vec, String as UTF-8, and HashMap, where ownership, borrowing, and now lifetimes all show up in working code.