-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Code
fn filter_guest_list_and_add_bob<'bob, 'guests: 'bob>(
guests: Vec<&'guests str>,
bob: &'bob str,
) -> Vec<&'guests str> {
let mut filtered: Vec<&'guests str> = Vec::new();
for g in guests {
if g.starts_with("vip") {
filtered.push(g);
}
}
filtered.push(bob);
filtered
}
Current output
error: lifetime may not live long enough
--> src/main.rs:5:23
|
1 | fn filter_guest_list_and_add_bob<'bob, 'guests: 'bob>(
| ---- ------- lifetime `'guests` defined here
| |
| lifetime `'bob` defined here
...
5 | let mut filtered: Vec<&'guests str> = Vec::new();
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'bob` must outlive `'guests`
|
= help: consider adding the following bound: `'bob: 'guests`
error: aborting due to 1 previous error
Desired output
error: lifetime may not live long enough
--> src/main.rs:11:23
|
1 | fn filter_guest_list_and_add_bob<'bob, 'guests: 'bob>(
| ---- ------- lifetime `'guests` outlives `'bob`
| |
| lifetime `'bob` defined here
...
11 | filtered.push(bob);
| ^^^ `filtered` requires values that live at least as long as `'guests` but `'guests` outlive `'bob`
|
Rationale and extra context
If I mix incompatible lifetimes at the use of a function/method I expect to have that location highlighted in the diagnostic so I can see whether the definition or use is wrong. This is what "normal type errors" already do:
For example if I swap the lifetimes & strings for types u32
& u16
I get a much more intuitive error highlighting which line caused filtered
to be inferred as u32
and then a subsequent type mismatch at the site of the second push
:
fn filter_guest_list_and_add_bob(guests: Vec<u32>, bob: u16) -> Vec<u32> {
let mut filtered = Vec::new();
for g in guests {
if g < 100 {
filtered.push(g);
}
}
filtered.push(bob);
filtered
}
More intuitive error:
error[E0308]: mismatched types
--> src/main.rs:8:19
|
5 | filtered.push(g);
| -------- - this argument has type `u32`...
| |
| ... which causes `filtered` to have type `Vec<u32>`
...
8 | filtered.push(bob);
| ---- ^^^ expected `u32`, found `u16`
| |
| arguments to this method are incorrect
|
note: method defined here
--> /Users/philogy/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2521:12
|
2521 | pub fn push(&mut self, value: T) {
| ^^^^
help: you can convert a `u16` to a `u32`
|
8 | filtered.push(bob.into());
| +++++++
error: aborting due to 1 previous error
Other cases
Rust Version
rustc 1.90.0 (1159e78c4 2025-09-14)
binary: rustc
commit-hash: 1159e78c4747b02ef996e55082b704c09b970588
commit-date: 2025-09-14
host: aarch64-apple-darwin
release: 1.90.0
LLVM version: 20.1.8
Anything else?
Even more confusing I get the same error but at the return expression if I don't add an explicit type:
fn filter_guest_list_and_add_bob<'bob, 'guests: 'bob>(
guests: Vec<&'guests str>,
bob: &'bob str,
) -> Vec<&'guests str> {
let mut filtered = Vec::new();
for g in guests {
if g.starts_with("vip") {
filtered.push(g);
}
}
filtered.push(bob);
filtered
}
Error:
error: lifetime may not live long enough
--> src/main.rs:12:5
|
1 | fn filter_guest_list_and_add_bob<'bob, 'guests: 'bob>(
| ---- ------- lifetime `'guests` defined here
| |
| lifetime `'bob` defined here
...
12 | filtered
| ^^^^^^^^ function was supposed to return data with lifetime `'guests` but it is returning data with lifetime `'bob`
|
= help: consider adding the following bound: `'bob: 'guests`
error: aborting due to 1 previous error
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.