Non-Lexical Lifetimes (NLL), Reborrowing & Variance
Lifetime Algebra & Non-Lexical Lifetimes
Lifetimes in Rust are not runtime durations; they are static compile-time regions of code over which a reference is guaranteed valid by the borrow checker. Under the Non-Lexical Lifetimes (NLL) engine (Polonius), lifetimes end at their last actual point of use, rather than surviving to the end of the enclosing syntactic scope block.
Subtyping & Variance
Variance describes how the subtyping relationship between types T and U relates to the subtyping relationship between generic types F<T> and F<U>:
| Type Constructor | Variance over 'a | Variance over T | Intuition |
|---|---|---|---|
&'a T | Covariant | Covariant | Can safely substitute a longer lifetime for a shorter one |
&'a mut T | Covariant | Invariant | Cannot substitute subtypes; would allow storing shorter lifetimes into longer-lived references! |
fn(T) -> U | N/A | Contravariant over T, Covariant over U | Function inputs can accept wider supertypes |
Reborrowing vs Moving
When you pass a mutable reference &mut T into a function or bind it to a new identifier, Rust performs a reborrow rather than a move:
fn append_token(tokens: &mut Vec, token_id: u32) {
tokens.push(token_id);
}
let mut stream = Vec::new();
let ref1 = &mut stream;
// Reborrow: ref1 is temporarily suspended, not consumed!
append_token(ref1, 42);
// ref1 is active and usable again here
ref1.push(99);
Rust 2024 Precise Lifetime Capturing (use<'a>)
In the Rust 2024 Edition, Return-Position impl Trait (RPIT) implicitly captures all in-scope type and lifetime parameters. To prevent accidental overcapturing of temporary lifetimes (such as a short-lived delimiter slice), use precise capturing syntax (+ use<'data>):
// Only captures 'data; callers can drop delimiter immediately!
pub fn tokenize_lines<'data, 'delim>(
payload: &'data str,
delimiter: &'delim str,
) -> impl Iterator<Item = &'data str> + use<'data> {
let sep = delimiter.chars().next().unwrap_or('\n');
payload.split(sep)
}
Diagnose borrow checker lifetimes, verify early drops under Non-Lexical Lifetimes (NLL), and test mutable invariant constraints.