Repository: rust
Issue: diagnostics for lifetime issues sometimes point to code unrelated to the issue
Labels: A-diagnostics,T-compiler

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

```rust
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...
}
```

([Playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f3d51947e5a1ceadf25149391883056a))

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
```

<!-- The following is not always necessary. -->
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>
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

### Context

I was working on a code refactoring involving many lifetime annotations (https://github.com/sunng87/handlebars-rust/pull/532) for my work on an efficient template cache in [SQLPage](https://github.com/lovasoa/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" to `get_self`, but it's not obvious.
 - Second, get_self doesn't require that `'a` must outlive `'b`. `get_self` doesn't even see more than one lifetime. The requirement happens later, when `f` is 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.