Code
fn push(vec: &mut Vec<&str>, s: &str, fun: impl Clone) {
vec.push(s);
}
Current output
Checking tst v0.1.0 (/tmp/tst)
error: lifetime may not live long enough
--> src/main.rs:4:5
|
1 | fn push(vec: &mut Vec<&str>, s: &str, fun: impl Clone) {
| - - let's call the lifetime of this reference `'1`
| |
| let's call the lifetime of this reference `'2`
2 | vec.push(s);
| ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
= note: requirement occurs because of a mutable reference to `Vec<&str>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: consider introducing a named lifetime parameter
|
1 | fn push(vec: &mut Vec<&'a str>, s: &'a str, fun: 'a, impl Clone) {
| ++ ++ +++
error: could not compile `tst` (bin "tst") due to 1 previous error
Desired output
Checking tst v0.1.0 (/tmp/tst)
error: lifetime may not live long enough
--> src/main.rs:4:5
|
1 | fn push(vec: &mut Vec<&str>, s: &str, fun: impl Clone) {
| - - let's call the lifetime of this reference `'1`
| |
| let's call the lifetime of this reference `'2`
2 | vec.push(s);
| ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
= note: requirement occurs because of a mutable reference to `Vec<&str>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: consider introducing a named lifetime parameter
|
1 | fn push<'a>(vec: &mut Vec<&'a str>, s: &'a str, fun: impl Clone) {
| ++++ ++ ++
error: could not compile `tst` (bin "tst") due to 1 previous error
Rationale and extra context
The diagnostic is broken in several ways:
- it doesn't actually introduce the lifetime parameter (
<'a>)
- it adds an
'a, before impl Clone, which is:
- syntactically invalid
- unnecessary, since
fun isn't even related to the error
Other cases
If I add a reference before the impl Trait:
fn push(vec: &mut Vec<&str>, s: &str, fun: &impl Clone) {
vec.push(s);
}
the 'a, is added after it:
help: consider introducing a named lifetime parameter
|
1 | fn push(vec: &mut Vec<&'a str>, s: &'a str, fun: &'a, impl Clone) {
| ++ ++ +++
If I switch to a trait object:
fn push(vec: &mut Vec<&str>, s: &str, fun: &dyn Drop) {
vec.push(s);
}
(ignore the trait change -- &impl Drop is broken in the same way as &impl Clone)
then the suggestion is actually correct:
help: consider introducing a named lifetime parameter
|
1 | fn push<'a>(vec: &mut Vec<&'a str>, s: &'a str, fun: &dyn Drop) {
| ++++ ++ ++
Rust Version
rustc 1.96.1 (31fca3adb 2026-06-26)
binary: rustc
commit-hash: 31fca3adb283cc9dfd56b49cdee9a96eb9c96ffd
commit-date: 2026-06-26
host: x86_64-unknown-linux-gnu
release: 1.96.1
LLVM version: 22.1.2
Anything else?
This is probably because this:
fn push(vec: &mut Vec<&str>, s: &str, fun: impl Clone) {
vec.push(s);
}
desugars to this:
fn push<T: Clone>(vec: &mut Vec<&str>, s: &str, fun: T) {
vec.push(s);
}
and so the suggestion thinks the generics block is already present, and tries to add 'a, to it:
fn push<'a, T: Clone>(vec: &mut Vec<&'a str>, s: &'a str, fun: T) {
// +++ ++ ++
vec.push(s);
}
Code
Current output
Desired output
Rationale and extra context
The diagnostic is broken in several ways:
<'a>)'a,beforeimpl Clone, which is:funisn't even related to the errorOther cases
If I add a reference before the
impl Trait:the
'a,is added after it:If I switch to a trait object:
(ignore the trait change --
&impl Dropis broken in the same way as&impl Clone)then the suggestion is actually correct:
Rust Version
Anything else?
This is probably because this:
desugars to this:
and so the suggestion thinks the generics block is already present, and tries to add
'a,to it: