/errors/rust/e0106-missing-lifetime-specifier
Rust error[E0106]: missing lifetime specifier
verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · rustc 1.98.1 (48a229cea 2026-09-01)updated
- tool
- Rust
- exit code
- 1
- versions
- Rust 1.x (2018, 2021 and 2024 editions)
- os
- any
error[E0106]: missing lifetime specifier means a reference in a signature or a type needs a lifetime that the compiler cannot infer. For functions, Rust fills in lifetimes automatically (lifetime elision) only when there is exactly one input reference, or a &self. With two reference parameters and a returned reference, or with a reference stored in a struct, you have to write the lifetime: fn longest<'a>(x: &'a str, y: &'a str) -> &'a str, or return an owned String.
Reproduce it
cat > main.rs <<'EOF'
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}
struct Parser {
input: &str,
}
fn main() {
let p = Parser { input: "abc" };
println!("{} {}", longest("hi", "there"), p.input);
}
EOF
rustc --edition 2021 main.rs 2>&1 | grep -E '^(error|help)'
exit ${PIPESTATUS[0]}Output · exit 1
error[E0106]: missing lifetime specifier help: consider introducing a named lifetime parameter error[E0106]: missing lifetime specifier help: consider introducing a named lifetime parameter error: aborting due to 2 previous errors
The compiler reports one E0106 for the return type of longest and one for the struct field, each with a help: line that suggests the lifetime parameter to add.
Fix: name the lifetime
cat > main.rs <<'EOF'
// The result lives as long as the shorter of the two inputs.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
// A struct that borrows must declare the lifetime of the borrow.
struct Parser<'a> {
input: &'a str,
}
// Owned return value: no lifetime needed.
fn greeting(name: &str, punct: &str) -> String {
format!("hello {name}{punct}")
}
fn main() {
let p = Parser { input: "abc" };
println!("{} {} {}", longest("hi", "there"), p.input, greeting("rust", "!"));
}
EOF
rustc --edition 2021 main.rs && ./mainOutput
there abc hello rust!
Elision rules in short
| Signature | Needs an explicit lifetime? |
|---|---|
| fn f(x: &str) -> &str | No: the output borrows from the only input |
| fn f(&self, y: &str) -> &str | No: the output borrows from self |
| fn f(x: &str, y: &str) -> &str | Yes: two inputs, the compiler cannot choose |
| fn f() -> &str | Yes: nothing to borrow from (use String or &'static str) |
| struct S { field: &str } | Yes: types never elide lifetimes (struct S<'a>) |
Sources
Related pages
errors · rustRust error[E0382]: borrow of moved valuerustc reports E0382 when a variable is used after its value moved to another binding or function. Borrow it with &, clone it, or reorder the code. Real output.errors · rustRust error[E0502]: cannot borrow as mutable because it is also borrowed as immutablerustc E0502: a shared reference is still alive when code needs &mut, as with v.push while holding &v[0]. Copy the value or end the borrow first. Real output.compare · rustRust String vs &str: what is the difference?String is an owned, growable, heap-allocated UTF-8 buffer; &str is a borrowed view into UTF-8 bytes. What to store, what to take as a parameter, conversions.