Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A generic lifetime parameter is a compile-time construct used by the Rust borrow checker to explicitly define the relationship between the scopes for which different references are valid. Unlike type parameters that abstract over data types, lifetime parameters abstract over the duration of a reference’s validity. They do not alter the actual lifespan of any value; rather, they provide the compiler with the necessary constraints to prove that references will not outlive the data they point to, thereby preventing dangling pointers.

Syntax and Declaration

Lifetime parameters are prefixed with an apostrophe (') and are conventionally named with lowercase letters starting from 'a. They are declared in angle brackets (<>) immediately following the name of a function, struct, enum, or trait, before being applied to the references within that item.
// Function with a single generic lifetime parameter
fn single_lifetime<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
    x
}

// Function with multiple generic lifetime parameters
fn multiple_lifetimes<'a, 'b>(x: &'a i32, y: &'b i32) {
    unimplemented!()
}

// Struct holding a reference requires a lifetime parameter
struct BorrowedData<'a> {
    data: &'a str,
}

// Implementation blocks must declare the lifetime parameter
impl<'a> BorrowedData<'a> {
    fn get_data(&self) -> &'a str {
        self.data
    }
}

Mechanics and Constraints

Intersection of Scopes When a single generic lifetime parameter (e.g., 'a) is applied to multiple input parameters, the borrow checker resolves the concrete lifetime to the intersection (the narrowest overlapping scope) of the actual lifetimes of the arguments passed at the call site. The return type annotated with 'a is then constrained to this intersected, shorter lifetime. Lifetime Bounds (The Outlives Relation) Just as generic types can be constrained with trait bounds, generic lifetimes can be constrained using lifetime bounds. The syntax 'a: 'b is read as “lifetime 'a outlives 'b”. This guarantees to the compiler that the memory referenced by a reference with lifetime 'a will be valid for at least as long as the memory referenced by a reference with lifetime 'b.
// 'a must live at least as long as 'b
fn outlives_relation<'a, 'b>(x: &'a i32, y: &'b i32) where 'a: 'b {
    todo!()
}

// Generic type T must not contain any references shorter than 'a
struct GenericBound<'a, T: 'a> {
    reference: &'a T,
}
The 'static Lifetime While generic lifetime parameters act as placeholders that the compiler fills with concrete scopes, Rust also provides an explicit, concrete lifetime named 'static. It denotes that the referenced data is available for the entire duration of the program’s execution. String literals are expressions that inherently have the type &'static str because their underlying string data is baked directly into the compiled binary.
static STATIC_STRING: &'static str = "Immutable binary data";

Lifetime Elision Rules

To reduce boilerplate, the Rust compiler applies a set of deterministic rules called “lifetime elision” to automatically infer generic lifetime parameters in function signatures. Explicit generic lifetime parameters are only required when these rules fail to resolve ambiguity. The compiler applies three rules to infer lifetimes:
  1. Input Rule: Each parameter that is a reference gets its own distinct generic lifetime parameter.
  2. Output Rule 1: If there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters.
  3. Output Rule 2: If there are multiple input lifetime parameters, but one of them is &self or &mut self (as in a method), the lifetime of self is assigned to all output lifetime parameters.
If the compiler applies all three rules and the output lifetimes are still ambiguous, it will throw a compilation error, requiring the developer to manually annotate the generic lifetime parameters.
Master Rust with Deep Grasping Methodology!Learn More