-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-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
Given the following code:
struct X<'a>(&'a ());
impl<'a> X<'a> {
fn get_self(&mut self) -> &mut X<'a> {
self
}
}
fn f<'a>(_y1: &'a mut X<'a>, _y2: &'a mut X<'a>) {}
fn g<'a, 'b>(x1: &mut X<'a>, x2: &mut X<'b>) {
let y1 = x1.get_self();
let y2 = x2.get_self();
// ... Potentially hundreds of lines of code here...
f(y1, y2);
// ... Potentially hundreds of lines of code here...
}The current output is:
error[[E0621]](https://doc.rust-lang.org/stable/error-index.html#E0621): explicit lifetime required in the type of `x1`
--> src/lib.rs:12:14
|
11 | fn g<'a, 'b>(x1: &mut X<'a>, x2: &mut X<'b>) {
| ---------- help: add explicit lifetime `'a` to the type of `x1`: `&'a mut X<'a>`
12 | let y1 = x1.get_self();
| ^^^^^^^^^^^^^ lifetime `'a` required
error: lifetime may not live long enough
--> src/lib.rs:12:14
|
11 | fn g<'a, 'b>(x1: &mut X<'a>, x2: &mut X<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
12 | let y1 = x1.get_self();
| ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of a mutable reference to `X<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> src/lib.rs:12:14
|
11 | fn g<'a, 'b>(x1: &mut X<'a>, x2: &mut X<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
12 | let y1 = x1.get_self();
| ^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of a mutable reference to `X<'_>`
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error[[E0621]](https://doc.rust-lang.org/stable/error-index.html#E0621): explicit lifetime required in the type of `x2`
--> src/lib.rs:13:14
|
11 | fn g<'a, 'b>(x1: &mut X<'a>, x2: &mut X<'b>) {
| ---------- help: add explicit lifetime `'a` to the type of `x2`: `&'a mut X<'b>`
12 | let y1 = x1.get_self();
13 | let y2 = x2.get_self();
| ^^^^^^^^^^^^^ lifetime `'a` required
help: `'a` and `'b` must be the same: replace one with the other
For more information about this error, try `rustc --explain E0621`.
error: could not compile `playground` due to 4 previous errors
Ideally the output should look like:
error: lifetime may not live long enough
--> src/lib.rs:15:4
15 | f(y1, y2);
| ^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= help: y2 has type &mut X<'b> but function `f` expected &mut X<'a>
Context
I was working on a code refactoring involving many lifetime annotations (sunng87/handlebars-rust#532) for my work on an efficient template cache in SQLPage, and this issue blocked me for way too long before I realized the compiler was pointing me in the wrong direction.
In the code snippet above, the first two lines in g are no-ops. The real issue is trying to call the function f with arguments that don't match its lifetime requirements.
But the compiler says something that made it very hard for me to figure out where the problem was :
x1.get_self();
^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
This sentence just seems wrong.
- First there doesn't seem to be any "argument" in the highlighted code. It looks like the compiler is referring to
x1, as an "argument" toget_self, but it's not obvious. - Second, get_self doesn't require that
'amust outlive'b.get_selfdoesn't even see more than one lifetime. The requirement happens later, whenfis called, but the compiler does not point to it, and the programmer has to find it himself, buried in potentially hundreds of lines of unrelated code.
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsT-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.