Skip to content
tezvyn:

Rust's Lifetime Elision: When You Can Skip 'a

Source: doc.rust-lang.orgMediumHow cards are made

Lifetime elision lets you omit explicit lifetimes ('a) in function signatures. The compiler infers them from common patterns, like a function taking one reference and returning one.

Why it exists

Manually annotating every lifetime for common, obvious borrowing patterns is tedious and clutters code. Lifetime elision was introduced to make idiomatic Rust more ergonomic by allowing the compiler to infer lifetimes in these frequent scenarios, reducing boilerplate without sacrificing safety.

The mental model

Think of lifetime elision as compiler-provided shortcuts for the most common borrowing scenarios. Instead of you telling the compiler "the output reference lives as long as this input reference," the compiler assumes it based on a few simple rules. If your function's borrowing pattern doesn't fit one of these rules, you must write the lifetimes out explicitly.

How it works

The compiler applies three rules to function signatures to infer elided lifetimes. First, each elided lifetime in an input parameter becomes a distinct lifetime parameter. Second, if there is exactly one input lifetime (elided or not), that lifetime is assigned to all elided output lifetimes. Third, if one of the parameters is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes. If these rules don't resolve all lifetimes, the compiler reports an error.

When to use it

You use elision constantly, often without thinking about it. It's designed for the most common function signatures. For example, a function that takes a slice and returns a sub-slice, like fn first_three(s: &[i32]) -> &[i32], relies on elision. Similarly, a method on a struct that returns a reference to one of its own fields, like fn get_name(&self) -> &String, uses the &self elision rule.

When not to use it

You cannot use elision when the lifetime relationships are ambiguous. The classic case is a function that takes two string slices and returns one, like fn longest(x: &str, y: &str) -> &str. The compiler doesn't know if the returned slice should be tied to x's lifetime or y's. You must be explicit: fn longest<'a>(x: &'a str, y: &'a str) -> &'a str. It also fails for functions that return a reference without taking any reference inputs.

One canonical example

A function to find the first word in a string, fn first_word(s: &str) -> &str, is a perfect example. It uses lifetime elision. Because there is only one input reference, the compiler applies the second rule and expands the signature to fn first_word<'a>(s: &'a str) -> &'a str behind the scenes. This correctly enforces that the returned string slice cannot outlive the input string slice it was derived from.

Interview question

Which function signature would require explicit lifetime annotations because Rust's lifetime elision rules cannot infer them?

  • a.fn compare_strings(a: &str, b: &str) -> &strCorrect
  • b.fn process_data(data: &mut [u8])
  • c.fn find_first_char(s: &str) -> &char
  • d.fn get_value(&self) -> &str
Why?

The function `compare_strings` takes two input references and returns one, creating an ambiguous scenario where the compiler cannot determine which input's lifetime the output should inherit, thus requiring explicit annotation. In contrast, `find_first_char` has only one input reference, allowing elision rule 2 to apply.

Just read this? Test yourself on what you have been reading.

Read the original → doc.rust-lang.org

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on rust — each one lists the topics its interview covers.

See open roles