| |

Rust 44 🦀 Lifetime Elision Rules

Every reference in Rust has a lifetime, but most of them are never written. The compiler infers them from the code using a small set of rules called the lifetime elision rules. The rules were introduced in Rust 1.0 to reduce the noise in function signatures, and they cover the vast majority of functions. Before the rules, every function that took a reference and returned a reference required an explicit 'a annotation, even when the relationship was obvious. The elision rules make the common cases implicit, and the explicit annotation is reserved for the cases where the relationship is genuinely ambiguous.

The rules are three, and they are applied in order. The first rule applies to the inputs: every reference parameter gets its own lifetime parameter. The second rule applies to the outputs when there is exactly one input lifetime: the output’s lifetime is the input’s lifetime. The third rule applies to methods: if there is a &self or &mut self parameter, its lifetime is assigned to all output lifetimes. If, after all three rules, an output lifetime is still unspecified, the compiler reports an error and requires the developer to write the annotation.

The rules are not arbitrary. They encode the two most common patterns: a function that returns a reference derived from its single input, and a method that returns a reference derived from self. These patterns cover the majority of real-world functions, so the annotations that remain are the ones where the relationship is genuinely worth documenting. Understanding the rules is what allows a developer to read a signature like fn f(x: &str, y: &str) -> &str and know immediately that it does not compile, and to read fn f(&self, x: &str) -> &str and know that the output borrows from self.

This chapter covers three areas. First, why elision exists — the annotation-noise problem and the design goals of the rules. Second, the three rules in detail — the input rule, the output rule, the method rule, and the order in which they apply. Third, the cases where elision does not apply — multiple inputs with a returned reference, the 'static lifetime, and the interaction with generics and trait objects. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the rule application.

Key point: The lifetime elision rules infer the lifetimes of references in function and method signatures. Rule 1: each input reference gets its own lifetime. Rule 2: if there is exactly one input lifetime, it is assigned to all outputs. Rule 3: if there is a &self or &mut self, its lifetime is assigned to all outputs. If an output lifetime remains unspecified after the rules, the compiler requires an explicit annotation.


Why lifetime elision exists

The annotation-noise problem. Before elision, every function that took a reference and returned a reference had to write the lifetime parameter. A function like fn first_word<'a>(s: &'a str) -> &'a str was the norm, even though the relationship is obvious: the output borrows from the single input. A library with hundreds of such functions was cluttered with lifetime parameters that added no information. The elision rules remove the noise by inferring the obvious cases.

The pattern problem. The two most common patterns in Rust are “return a reference derived from the single input” and “return a reference derived from self.” The first pattern appears in functions like first_word, trim, and split. The second appears in methods like get, iter, and as_str. The elision rules encode these patterns directly: the single input’s lifetime is the output’s lifetime, and &self‘s lifetime is the output’s lifetime. The rules are a form of default: when the relationship is the common one, the annotation is unnecessary.

The readability problem. A signature with lifetime parameters is harder to read than one without. The parameters are noise when the relationship is obvious, and they distract from the function’s actual types. The elision rules make the common signatures readable: fn first_word(s: &str) -> &str is clearer than fn first_word<'a>(s: &'a str) -> &'a str, even though the two are equivalent. The explicit annotation is reserved for the cases where the relationship is not obvious, and there it serves as documentation.

The ambiguity problem. The elision rules cannot infer the lifetime when the relationship is ambiguous. A function with two input references and a returned reference has no rule that assigns the output’s lifetime. The compiler reports an error, and the developer must write the annotation. The error is the compiler’s way of saying “the relationship is not obvious; please document it.” The explicit annotation resolves the ambiguity and serves as the contract with the caller.

The method-receiver problem. A method’s &self parameter is special. It is the receiver, and the convention is that a method that returns a reference returns one derived from self. The third rule encodes this convention. Without it, every method that returns a reference would need an annotation, which would be a significant amount of noise. The rule is what makes the method signatures in the standard library readable.

The trade-off. The elision rules are a form of implicit information. A reader who does not know the rules cannot determine the lifetimes from the signature alone. The rules must be learned, and the learning is a small cost compared to the readability they provide. The alternative — writing every lifetime explicitly — would be more explicit but also more verbose, and the verbosity would obscure the signatures that genuinely need the annotation. The trade-off is between explicitness and readability, and the rules favor readability for the common cases.


a. Rule 1: each input reference gets its own lifetime

The first rule applies to the input parameters. Every reference parameter is assigned a distinct lifetime parameter. The lifetimes are anonymous in the elided form, but they exist in the compiler’s view.

fn f(x: &str, y: &str) {
    // ...
}

The elided form is equivalent to:

fn f<'a, 'b>(x: &'a str, y: &'b str) {
    // ...
}

Each input reference gets its own lifetime parameter. The two lifetimes are independent, and the compiler does not assume any relationship between them.

The rule applies to all input references, regardless of their position in the parameter list. A function with three input references gets three lifetime parameters, a function with one gets one, and a function with none gets none.

fn f(x: &str, y: i32, z: &str) {
    // ...
}

The elided form is fn f<'a, 'b>(x: &'a str, y: i32, z: &'b str). The i32 parameter has no lifetime, so it does not contribute a lifetime parameter. The two references get separate lifetimes.

The rule does not apply to the return type. The input lifetimes are declared, but the output’s lifetime is determined by the next rule.


b. Rule 2: one input lifetime is assigned to the output

The second rule applies when there is exactly one input lifetime. In that case, the output’s lifetime is the input’s lifetime. This is the rule that makes fn first_word(s: &str) -> &str compile without an annotation.

fn first_word(s: &str) -> &str {
    s.split_whitespace().next().unwrap_or("")
}

The elided form is equivalent to:

fn first_word<'a>(s: &'a str) -> &'a str {
    s.split_whitespace().next().unwrap_or("")
}

The input’s lifetime 'a is assigned to the output. The returned reference is valid for as long as the input reference is valid.

The rule applies only when there is exactly one input lifetime. If the function has two input references, the rule does not apply, and the output’s lifetime is unspecified. The compiler reports an error, and the developer must write the annotation.

// ❌ Does not compile: two input lifetimes, one output
// fn longest(x: &str, y: &str) -> &str { ... }

// ✅ The annotation resolves the ambiguity
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

The rule also applies when the function has one input reference and one output reference, even if there are other non-reference parameters. A function with fn f(x: &str, n: i32) -> &str has one input lifetime, so the output’s lifetime is x‘s lifetime.

fn first_n(x: &str, n: usize) -> &str {
    &x[..n.min(x.len())]
}

The elided form is fn first_n<'a>(x: &'a str, n: usize) -> &'a str. The n parameter has no lifetime, so it does not contribute a lifetime parameter. The output borrows from x.


c. Rule 3: the &self lifetime is assigned to the output

The third rule applies to methods. If there is a &self or &mut self parameter, its lifetime is assigned to all output lifetimes. This is the rule that makes the method signatures in the standard library readable.

struct Excerpt<'a> {
    text: &'a str,
}

impl<'a> Excerpt<'a> {
    fn text(&self) -> &str {
        self.text
    }
}

The elided form of the method is:

fn text<'b>(&'b self) -> &'b str {
    self.text
}

The lifetime of &self is assigned to the output. The returned reference is valid for as long as the borrow of self is valid. The struct’s own lifetime 'a is not involved in the method’s signature; it is the lifetime of the data the struct borrows.

The rule applies even when the method has other input references. A method with &self and an additional reference assigns &self‘s lifetime to the output, not the additional reference’s lifetime.

impl<'a> Excerpt<'a> {
    fn longer<'b>(&'a self, other: &'b str) -> &'a str {
        if self.text.len() > other.len() {
            self.text
        } else {
            self.text
        }
    }
}

In this example, the method has an explicit annotation because the output should borrow from self, not from other. The rule 3 would assign &self‘s lifetime to the output if the annotation were elided, but the explicit annotation makes the relationship clearer and allows other to have a different lifetime.

The rule 3 does not apply to associated functions that do not take &self. A function like fn new(input: &str) -> Excerpt has no &self, so the rule does not apply, and the output’s lifetime is determined by rule 2 (if there is exactly one input lifetime) or requires an annotation.

impl<'a> Excerpt<'a> {
    fn new(text: &'a str) -> Excerpt<'a> {
        Excerpt { text }
    }
}

The new function has one input reference and a returned struct with a lifetime. The elision rules do not apply directly to the return type because the return type is not a reference. The explicit annotation 'a is required to connect the input’s lifetime to the struct’s lifetime parameter.


Complete Example Session

// ============================================
// PART 1: RULE 1 — EACH INPUT GETS ITS OWN LIFETIME
// ============================================

fn f(x: &str, y: &str) {
    println!("{} {}", x, y);
}

// Elided form:
fn f_explicit<'a, 'b>(x: &'a str, y: &'b str) {
    println!("{} {}", x, y);
}

// Each input has its own lifetime.


// ============================================
// PART 2: RULE 2 — ONE INPUT, ONE OUTPUT
// ============================================

fn first_word(s: &str) -> &str {
    s.split_whitespace().next().unwrap_or("")
}

// Elided form:
fn first_word_explicit<'a>(s: &'a str) -> &'a str {
    s.split_whitespace().next().unwrap_or("")
}

// The input's lifetime is assigned to the output.


// ============================================
// PART 3: RULE 2 WITH A NON-REFERENCE PARAMETER
// ============================================

fn first_n(x: &str, n: usize) -> &str {
    &x[..n.min(x.len())]
}

// Elided form:
fn first_n_explicit<'a>(x: &'a str, n: usize) -> &'a str {
    &x[..n.min(x.len())]
}

// The n parameter has no lifetime.
// The output borrows from x.


// ============================================
// PART 4: RULE 2 DOES NOT APPLY WITH TWO INPUTS
// ============================================

// ❌ Does not compile:
// fn longest(x: &str, y: &str) -> &str {
//     if x.len() > y.len() { x } else { y }
// }

// ✅ The annotation resolves the ambiguity:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

// The compiler cannot know which input the output
// borrows from, so the annotation is required.


// ============================================
// PART 5: RULE 3 — &self IS ASSIGNED TO THE OUTPUT
// ============================================

struct Excerpt<'a> {
    text: &'a str,
}

impl<'a> Excerpt<'a> {
    fn text(&self) -> &str {
        self.text
    }
}

// Elided form:
impl<'a> Excerpt<'a> {
    fn text_explicit<'b>(&'b self) -> &'b str {
        self.text
    }
}

// &self's lifetime is assigned to the output.


// ============================================
// PART 6: RULE 3 WITH AN ADDITIONAL REFERENCE
// ============================================

impl<'a> Excerpt<'a> {
    fn longer<'b>(&'a self, other: &'b str) -> &'a str {
        if self.text.len() > other.len() {
            self.text
        } else {
            self.text
        }
    }
}

// The annotation says the output borrows from self, not other.
// Rule 3 would also assign &self's lifetime to the output,
// but the explicit annotation makes it clear.


// ============================================
// PART 7: NO &self — THE RULE DOES NOT APPLY
// ============================================

impl<'a> Excerpt<'a> {
    fn new(text: &'a str) -> Excerpt<'a> {
        Excerpt { text }
    }
}

// The new function has no &self.
// The elision rules do not connect the input to the struct's lifetime.
// The explicit annotation is required.


// ============================================
// PART 8: THE 'static LIFETIME
// ============================================

fn greeting() -> &'static str {
    "hello"
}

// The 'static lifetime is explicit.
// It is not inferred by the elision rules.


// ============================================
// PART 9: ELISION WITH GENERICS
// ============================================

fn first<'a, T>(items: &'a [T]) -> &'a T {
    &items[0]
}

// Elided form:
fn first_elided<T>(items: &[T]) -> &T {
    &items[0]
}

// The lifetime of the slice is assigned to the output.
// The type parameter T does not affect the elision.


// ============================================
// PART 10: THE COMPLETE EXAMPLE
// ============================================

struct Parser<'a> {
    input: &'a str,
    position: usize,
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Self {
        Parser { input, position: 0 }
    }

    fn rest(&self) -> &'a str {
        &self.input[self.position..]
    }

    fn peek(&self) -> Option<char> {
        self.rest().chars().next()
    }

    fn advance(&mut self) -> Option<char> {
        let c = self.peek()?;
        self.position += c.len_utf8();
        Some(c)
    }
}

fn main() {
    let input = String::from("hello world");
    let mut parser = Parser::new(&input);

    while let Some(c) = parser.advance() {
        print!("{}", c);
    }
    println!();
}

// rest returns &'a str, not &self's lifetime,
// because the slice borrows from the input.
// The explicit 'a annotation is required.
//
// peek and advance take &self and return Option<char>,
// which is not a reference, so no lifetime annotation is needed.

The ten parts show rule 1, rule 2, rule 2 with a non-reference parameter, rule 2 not applying with two inputs, rule 3, rule 3 with an additional reference, the no-&self case, the 'static lifetime, elision with generics, and the complete example.


Quick Reference

The Three Rules

RuleApplies toEffect
1Input referencesEach gets its own lifetime
2One input lifetimeAssigned to all outputs
3&self or &mut selfAssigned to all outputs

Rule Application Order

StepRuleCondition
1Input ruleAlways
2Output ruleExactly one input lifetime
3Method rule&self or &mut self present
4ErrorOutput lifetime unspecified

Common Signatures

SignatureElided form
fn f(x: &str) -> &strfn f<'a>(x: &'a str) -> &'a str
fn f(x: &str, y: &str)fn f<'a, 'b>(x: &'a str, y: &'b str)
fn f(x: &str, y: &str) -> &strError
fn m(&self) -> &strfn m<'a>(&'a self) -> &'a str
fn m(&self, x: &str) -> &strfn m<'a, 'b>(&'a self, x: &'b str) -> &'a str

When Elision Does Not Apply

CaseWhy
Two inputs, one output referenceAmbiguous
No &self, output is a struct with a lifetimeNo rule connects input to struct
'static returnMust be explicit
Multiple output references with different lifetimesMust be explicit

Best Practices

✅ Do This:

// Let elision handle the single-input case
fn first_word(s: &str) -> &str { ... }                                   // ✅
// Add annotations for multiple inputs
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { ... }                // ✅
// Let elision handle the &self case
impl S { fn get(&self) -> &str { self.value } }                           // ✅
// Use explicit annotations when the output borrows from a non-self parameter
fn longer<'a, 'b>(&'a self, other: &'b str) -> &'a str { ... }           // ✅
// Use 'static for string literals
fn greeting() -> &'static str { "hello" }                                 // ✅
// Add the lifetime to struct constructors
fn new(input: &'a str) -> Self { ... }                                    // ✅

❌ Don’t Do This:

// Don't omit the annotation with two inputs
fn longest(x: &str, y: &str) -> &str { ... } // error                      // ❌
// Don't annotate when elision works
fn first_word<'a>(s: &'a str) -> &'a str { ... } // unnecessary noise      // ❌
// Don't return a reference from a non-self parameter with &self's lifetime
fn get(&self, other: &str) -> &str { other } // wrong lifetime             // ❌
// Don't forget the struct lifetime in a constructor
fn new(input: &str) -> Excerpt { ... } // missing 'a                       // ❌
// Don't use 'static when a shorter lifetime suffices
fn f(s: &str) -> &'static str { s } // does not compile                    // ❌

Common Pitfalls

PitfallWhy It HappensFix
Missing lifetime specifierTwo inputs, one outputAdd the annotation
Over-annotatingElision already worksRemove the annotation
Wrong output lifetimeOutput borrows from a parameterAnnotate the relationship
Struct constructor missing lifetimeNo &self, struct has a lifetimeAdd the lifetime parameter
'static bound not satisfiedBorrowed data escapesMove the data into the closure
Method returns &self‘s lifetime but should return input’sWrong annotationUse the input’s lifetime

Real-World Examples

1. Single Input

fn first_word(s: &str) -> &str { ... }

2. Multiple Inputs

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { ... }

3. Method with &self

impl S { fn get(&self) -> &str { self.value } }

4. Method with Additional Reference

impl<'a> S<'a> { fn longer<'b>(&'a self, other: &'b str) -> &'a str { ... } }

5. Struct Constructor

impl<'a> Excerpt<'a> { fn new(text: &'a str) -> Self { ... } }

6. ‘static

fn greeting() -> &'static str { "hello" }

7. Generic Function

fn first<T>(items: &[T]) -> &T { &items[0] }

8. Two Inputs, Separate Lifetimes

fn first<'a, 'b>(x: &'a str, y: &'b str) -> &'a str { x }

9. Parser with Input Lifetime

impl<'a> Parser<'a> { fn rest(&self) -> &'a str { ... } }

10. Complete Example

fn first_word(s: &str) -> &str { s.split_whitespace().next().unwrap_or("") }

Visual

The Elision Rule Application

┌──────────────────────────────────────────────────────────────┐
│  THE ELISION RULE APPLICATION                                │
│                                                              │
│  Signature: fn f(x: &str, y: &str) -> &str                   │
│                                                              │
│  STEP 1: Apply the input rule (rule 1).                      │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  fn f<'a, 'b>(x: &'a str, y: &'b str) -> &str        │    │
│  │                                                       │    │
│  │  Each input gets its own lifetime.                   │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 2: Apply the output rule (rule 2).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Exactly one input lifetime? NO (two inputs)         │    │
│  │  → rule 2 does not apply                             │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 3: Apply the method rule (rule 3).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Is there a &self or &mut self? NO                   │    │
│  │  → rule 3 does not apply                             │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 4: The output lifetime is unspecified.                 │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  ERROR: missing lifetime specifier                   │    │
│  │  The developer must write the annotation.            │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Rule 2 in Action

┌──────────────────────────────────────────────────────────────┐
│  RULE 2 IN ACTION                                            │
│                                                              │
│  Signature: fn first_word(s: &str) -> &str                   │
│                                                              │
│  STEP 1: Apply the input rule (rule 1).                      │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  fn first_word<'a>(s: &'a str) -> &str               │    │
│  │                                                       │    │
│  │  One input, one lifetime 'a.                         │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 2: Apply the output rule (rule 2).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Exactly one input lifetime? YES ('a)                │    │
│  │  → assign 'a to the output                           │    │
│  │                                                       │    │
│  │  fn first_word<'a>(s: &'a str) -> &'a str            │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 3: Apply the method rule (rule 3).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Is there a &self? NO                                │    │
│  │  → rule 3 does not apply                             │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  All output lifetimes are specified.                         │
│  No annotation is needed.                                    │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Rule 3 in Action

┌──────────────────────────────────────────────────────────────┐
│  RULE 3 IN ACTION                                            │
│                                                              │
│  Signature: fn get(&self) -> &str                            │
│                                                              │
│  STEP 1: Apply the input rule (rule 1).                      │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  fn get<'a>(&'a self) -> &str                        │    │
│  │                                                       │    │
│  │  One input: &self, with lifetime 'a.                 │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 2: Apply the output rule (rule 2).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Exactly one input lifetime? YES ('a)                │    │
│  │  → assign 'a to the output                           │    │
│  │                                                       │    │
│  │  fn get<'a>(&'a self) -> &'a str                     │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 3: Apply the method rule (rule 3).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Is there a &self? YES                               │    │
│  │  → &self's lifetime is assigned to the output        │    │
│  │  → already done by rule 2 in this case               │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  All output lifetimes are specified.                         │
│  No annotation is needed.                                    │
│                                                              │
└──────────────────────────────────────────────────────────────┘

A Method with &self and an Additional Reference

┌──────────────────────────────────────────────────────────────┐
│  METHOD WITH &self AND AN ADDITIONAL REFERENCE               │
│                                                              │
│  Signature: fn longer(&self, other: &str) -> &str            │
│                                                              │
│  STEP 1: Apply the input rule (rule 1).                      │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  fn longer<'a, 'b>(&'a self, other: &'b str) -> &str │    │
│  │                                                       │    │
│  │  Two input lifetimes: 'a for self, 'b for other.     │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 2: Apply the output rule (rule 2).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Exactly one input lifetime? NO (two inputs)         │    │
│  │  → rule 2 does not apply                             │    │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  STEP 3: Apply the method rule (rule 3).                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  Is there a &self? YES                               │    │
│  │  → assign 'a (self's lifetime) to the output         │    │
│  │                                                       │    │
│  │  fn longer<'a, 'b>(&'a self, other: &'b str) -> &'a str│  │
│  └──────────────────────────────────────────────────────┘    │
│    │                                                         │
│    ▼                                                         │
│  All output lifetimes are specified.                         │
│  The output borrows from self, not from other.               │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Summary

ItemValue
ElisionThe compiler infers lifetimes from the code
Rule 1Each input reference gets its own lifetime
Rule 2One input lifetime → assigned to all outputs
Rule 3&self or &mut self → assigned to all outputs
Annotation requiredMultiple inputs, returned reference
Annotation not neededSingle input, returned reference
Method rule&self assigned to the output
'staticMust be explicit
Struct constructorExplicit lifetime required

Key takeaways:

  • The elision rules infer the lifetimes for most functions. The rules are applied in order: the input rule, the output rule, and the method rule. If an output lifetime remains unspecified after the rules, the compiler reports an error and requires an annotation.
  • Rule 1 gives each input reference its own lifetime. The lifetimes are independent, and the compiler does not assume a relationship between them.
  • Rule 2 assigns the single input lifetime to the output. A function with one input reference and one output reference does not need an annotation, because the output borrows from the input.
  • Rule 3 assigns &self‘s lifetime to the output. A method that takes &self and returns a reference does not need an annotation, because the output borrows from self.
  • The annotation is required when the elision is ambiguous. A function with two input references and a returned reference has no rule that assigns the output’s lifetime, so the developer must write the annotation.
  • The rules do not apply to the 'static lifetime. A function that returns a 'static reference must write the lifetime explicitly.
  • Struct constructors require an explicit annotation. A function like fn new(input: &str) -> Self has no &self, and the return type is a struct with a lifetime, so the elision rules do not connect the input to the struct’s lifetime.
  • The rules are a form of default. They encode the two most common patterns: return a reference from the single input, and return a reference from &self. The explicit annotation is reserved for the cases where the relationship is not the common one.

Remember: The lifetime elision rules infer the lifetimes of references in function and method signatures. Rule 1 gives each input reference its own lifetime. Rule 2 assigns the single input lifetime to the output. Rule 3 assigns &self‘s lifetime to the output. The rules are applied in order, and the explicit annotation is required only when the rules do not specify an output lifetime. The rules cover the majority of functions, and the annotations that remain are the ones where the relationship between the inputs and the output is genuinely ambiguous. Understanding the rules is what allows a developer to read a signature and know the lifetimes without seeing the annotations.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!