← Back to Rust Course | Chapter 12: Lifetimes | Lesson 6 of 6

Lifetime Elision Rules

Lifetime elision is Rust quietly filling in the obvious lifetime labels for you, so you don't have to write them by hand every time.
Syntax
rust
fn function_name(param: &Type) -> &Type { ... }   // one input: elided

impl StructName {
    fn method_name(&self) -> &Type { ... }          // uses self's lifetime
}

fn function_name<'a>(a: &'a Type, b: &'a Type) -> &'a Type { ... }

Elision Rule: One Input, One Output

When a function has exactly one reference parameter and returns a reference, the compiler automatically assumes the output lifetime matches the input's, with no annotation needed.

Example: Elision Rule: One Input, One Output

markup
// Define the function `first_word` taking `s` and returning a string slice
fn first_word(s: &str) -> &str {
    // Match on `s.find(' ')` and branch by pattern
    match s.find(' ') {
        Some(i) => &s[..i],
        None => s,
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Print "{}" to the console, substituting in `first_word("hello world")` (with a trailing newline)
    println!("{}", first_word("hello world"));
}

Elision in Methods Using self

For methods taking &self, the elision rules assign the lifetime of self to any elided reference in the return type, which is why so many getter-style methods need no explicit lifetime syntax.

Example: Elision in Methods Using self

markup
// Define a struct `Container` to group related fields together
struct Container {
    text: String,
}

// Implement methods on `Container`
impl Container {
    // Define the function `get_text` taking `&self` and returning a string slice
    fn get_text(&self) -> &str {
        &self.text
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `c`, set to `Container { text: String::from("elided lifetime works here") }`
    let c = Container { text: String::from("elided lifetime works here") };
    // Print "{}" to the console, substituting in `c.get_text()` (with a trailing newline)
    println!("{}", c.get_text());
}

When Elision Is Not Enough

With more than one reference parameter and no self, the compiler cannot guess which input the output relates to, so an explicit lifetime annotation becomes necessary.

Example: When Elision Is Not Enough

markup
fn pick_longer<'a>(a: &'a str, b: &'a str) -> &'a str {
    // Check whether `a.len() > b.len() { a } else { b }`
    if a.len() > b.len() { a } else { b }
}

// Entry point: execution of the program starts here
fn main() {
    // Print "{}" to the console, substituting in `pick_longer("short", "much longer")` (with a trailing newline)
    println!("{}", pick_longer("short", "much longer"));
}

Elision Reduces Boilerplate

Because of these rules, the vast majority of everyday Rust functions involving references need zero explicit lifetime syntax, and annotations only appear when the relationship is genuinely ambiguous.

Example: Elision Reduces Boilerplate

markup
// Define the function `trim_and_return` taking `s` and returning a string slice
fn trim_and_return(s: &str) -> &str {
    s.trim()
}

// Entry point: execution of the program starts here
fn main() {
    // Print "[{}]" to the console, substituting in `trim_and_return("   padded   ")` (with a trailing newline)
    println!("[{}]", trim_and_return("   padded   "));
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Writing out explicit lifetime annotations for simple functions the elision rules already handle automatically, adding unnecessary noise.
  2. Assuming elision applies to every function shape -- it only covers a specific set of common patterns; anything more complex still needs explicit annotations.
  3. Forgetting that a method taking &self uses self's lifetime for any elided return reference, by the third elision rule.
Chapter Summary
  • Lifetime elision rules let the compiler infer lifetimes for common, simple function signatures without explicit annotations.
  • Rule one: each reference parameter gets its own inferred lifetime.
  • Rule two: if there is exactly one input lifetime, it is assigned to all elided output lifetimes.
  • Rule three: for methods, the lifetime of &self is assigned to elided output lifetimes.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.