Repository: rust
Issue: Misleading suggestion to add lifetime bounds
Labels: A-diagnostics,T-compiler

### Code

```Rust
pub struct Foo {
}
pub struct Bar<'f> {
    pub foo: &'f mut Foo,
}
pub struct Quux<'b, 'f> {
    pub bar: &'b mut Bar<'f>,
}

impl<'f> Bar<'f> {
    pub fn quux<'b>(&'b mut self) -> Quux {
        Quux { bar: self }
    }
}

#[test]
fn test_bar() {
    let mut foo = Foo {};
    let mut bar = Bar { foo: &mut foo };
    let quux = bar.quux();
    drop(quux);
    let _quux2 = bar.quux();
}
```


### Current output

```Shell
error: lifetime may not live long enough
  --> src/lib.rs:12:9
   |
10 | impl<'f> Bar<'f> {
   |      -- lifetime `'f` defined here
11 |     pub fn quux<'b>(&'b mut self) -> Quux {
   |                 -- lifetime `'b` defined here
12 |         Quux { bar: self }
   |         ^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'f` but it is returning data with lifetime `'b`
   |
   = help: consider adding the following bound: `'b: 'f`
   = note: requirement occurs because of the type `Quux<'_, '_>`, which makes the generic argument `'_` invariant
   = note: the struct `Quux<'b, 'f>` is invariant over the parameter `'f`
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
```


### Desired output

```Shell
help: consider annotating the return type to satisfy the necessary bounds: `Quux<'_, 'f>`
```


### Rationale and extra context

The suggestion "consider adding the following bound: `'b: 'f`" is incorrect in this case. That gets me back to the original error I was trying to solve (which is "error[E0499]: cannot borrow `bar` as mutable more than once at a time").

The correct suggestion is that the return type needs to be explicitly annotated:
```rust
    pub fn quux<'b>(&'b mut self) -> Quux<'b, 'f> {
```

(In this case, it's actually sufficient to just annotate it `Quux<'_, 'f>`.)

To be honest, I don't understand what the compiler means when it says "type `Quux<'_, '_>`, which makes the generic argument `'_` invariant". Maybe if I understood that, I might have been able to see the correct solution sooner. But even if I had, the "help" suggestion that the compiler suggests is not a correct fix here.

### Other cases

Adding/removing a lifetime annotation here or there can easily bring you to wildly different errors, none of which teach you the correct solution.

My original definition for `Quux` was
```Rust
pub struct Quux<'a> {
    pub bar: &'a mut Bar<'a>,
}
```
After a long time, I figured out that this doesn't work because it effectively tells the compiler "as long as `Bar` lives, so must `Quux`", which leads to a contradiction. That led me to put two lifetimes on `Quux`, but that change _by itself_ doesn't fix the problem.

If you do
```Rust
impl<'f> Bar<'f> {
    pub fn quux(&mut self) -> Quux {
        Quux { bar: self }
    }
}
```
then the error you get is
```text
error: lifetime may not live long enough
  --> src/lib.rs:12:9
   |
10 | impl<'f> Bar<'f> {
   |      -- lifetime `'f` defined here
11 |     pub fn quux(&mut self) -> Quux {
   |                 - let's call the lifetime of this reference `'1`
12 |         Quux { bar: self }
   |         ^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'f` but it is returning data with lifetime `'1`
   |
   = note: requirement occurs because of the type `Quux<'_, '_>`, which makes the generic argument `'_` invariant
   = note: the struct `Quux<'b, 'f>` is invariant over the parameter `'f`
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
```

This message doesn't provide any suggestion for how to change it. By pointing to the `&mut self` parameter, I thought the fix was to annotate the lifetime as `&'f mut self`. (Yes, that's the wrong lifetime, but when I only had a single lifetime named `'a`, there was only the one choice for what lifetime to put if it wanted an explicit lifetime.)

Doing that, however, yields this messages, which is what _originally_ got me into this mess:
```text
error[E0499]: cannot borrow `bar` as mutable more than once at a time
  --> src/lib.rs:22:18
   |
20 |     let quux = bar.quux();
   |                ---------- first mutable borrow occurs here
21 |     drop(quux);
22 |     let _quux2 = bar.quux();
   |                  ^^^^^^^^^^
   |                  |
   |                  second mutable borrow occurs here
   |                  first borrow later used here
```
This was _extremely_ confusing, because it wasn't apparent _why_ `bar` must live that long. Why does doing `bar.quux()` a second time use the first borrow at all?

If you change it to something obviously wrong, like
```Rust
    let quux = bar.quux();
    let _quux2 = bar.quux();
    drop(quux);
```
then you get
```text
error[E0499]: cannot borrow `bar` as mutable more than once at a time
  --> src/lib.rs:21:18
   |
20 |     let quux = bar.quux();
   |                ---------- first mutable borrow occurs here
21 |     let _quux2 = bar.quux();
   |                  ^^^^^^^^^^ second mutable borrow occurs here
22 |     drop(quux);
   |          ---- first borrow later used here
```
which is definitely clearer, and fairly obvious why it's incorrect. But the former message doesn't explain at all why the second `bar.quux()` would need both borrows to be alive at the same time.

For a while I thought there might be something magical about `self` that was affecting the lifetime. I tried implementing equivalent functions outside of a struct using ordinary parameters:
```Rust
fn get_quux<'b, 'f>(bar: &'b mut Bar<'f>) -> Quux {
    Quux { bar }
}

#[test]
fn test_bar_no_struct() {
    let mut foo = Foo {};
    let mut bar = Bar { foo: &mut foo };
    let quux = get_quux(&mut bar);
    drop(quux);
    let quux2 = get_quux(&mut bar);
}
```

This gives a completely different error, which is _much_ more helpful!
```text
error[E0106]: missing lifetime specifiers
    --> src/lib.rs:1129:46
     |
1129 | fn get_quux<'b, 'f>(bar: &'b mut Bar<'f>) -> Quux {
     |                          ---------------     ^^^^ expected 2 lifetime parameters
     |
     = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
note: these named lifetimes are available to use
    --> src/lib.rs:1129:13
     |
1129 | fn get_quux<'b, 'f>(bar: &'b mut Bar<'f>) -> Quux {
     |             ^^  ^^
help: consider using one of the available lifetimes here
     |
1129 | fn get_quux<'b, 'f>(bar: &'b mut Bar<'f>) -> Quux<'lifetime, 'lifetime> {
     |                                                  ++++++++++++++++++++++
```

### Anything else?

_No response_