Rustlers Atom 2.6: NLL (non-lexical lifetimes)
April 18, 2026•383 words
For a long time, Rust’s concept of a "lifetime" was strictly tied to lexical scope—the curly braces {}. If you created a reference inside a block, the compiler assumed that reference lived until the closing brace }, period.
This was safe, but annoying. It often rejected valid code because the compiler wasn't smart enough to see that you were done with a variable before the block ended.
Since the 2018 edition, Rust uses Non-Lexical Lifetimes (NLL). The borrow checker now looks at the control flow graph of your program. It knows that a reference’s life ends the last time it is used, not necessarily when it goes out of scope.
The "Interleaved" Borrows
Before NLL, the following code would fail to compile because mut_ref would "lock" the data variable until the end of the function. With NLL, Rust sees that mut_ref is used for the last time in the push line, so it releases the borrow immediately after.
fn main() {
let mut data = vec![1, 2, 3];
// 1. Create a mutable reference
let mut_ref = &mut data;
mut_ref.push(4);
// --- `mut_ref` is no longer used after this point ---
// Under NLL, the mutable borrow effectively ends HERE.
// 2. Create an immutable reference
// This is now allowed because the mutable borrow is "dead"
let imm_ref = &data;
println!("{:?}", imm_ref);
}
This feature reduces the need for "fighting the borrow checker." You don't need to artificially wrap code in extra {} blocks just to kill a borrow early. You can write code that flows naturally, and if the logic is sound, Rust will likely accept it.
Important Nuance: Drop vs. Liveness
NLL changes the liveness of references (when a borrow is active). It does not change when a value is dropped.
- Borrows end at the last usage.
- Owned values are dropped at the closing brace
}.
struct LoudDrop;
impl Drop for LoudDrop {
fn drop(&mut self) { println!("Dropped!"); }
}
fn main() {
let x = LoudDrop;
let y = &x;
println!("Used y");
// y's borrow ends here (NLL)
println!("End of main");
} // x is dropped here (Lexical Scope)