Repository: rust
Issue: lifetime diagnostic reports lifetimes backwards with invariance or contravariance
Labels: A-diagnostics,A-lifetimes,A-borrow-checker,T-compiler,A-NLL,D-incorrect,A-variance

### Code

```Rust
trait Slice {
    type S<'a>: Copy
    where
        Self: 'a;
}

struct Foo<'a, L: Slice + 'a> {
    foo: L::S<'a>,
}

impl<'a, L: Slice + 'a> Foo<'a, L> {
    fn foo(&self) -> L::S<'_> {
        self.foo
    }
}
```


### Current output

```Shell
error: lifetime may not live long enough
  --> src/lib.rs:13:9
   |
11 | impl<'a, L: Slice + 'a> Foo<'a, L> {
   |      -- lifetime `'a` defined here
12 |     fn foo(&self) -> L::S<'_> {
   |            - let's call the lifetime of this reference `'1`
13 |         self.foo
   |         ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
```


### Desired output

```Shell
error: GAT parameters are invariant
  --> src/lib.rs:13:9
   |
11 | impl<'a, L: Slice + 'a> Foo<'a, L> {
   |      -- lifetime `'a` defined here
12 |     fn foo(&self) -> L::S<'_> {
   |            - let's call the lifetime of this reference `'1`
13 |         self.foo
   |         ^^^^^^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`

error: could not compile `playground` due to previous error
```


### Rationale and extra context

The current error seems to assume a typical covariant-situation error where one is trying to return a long-lived value from behind a short-lived reference, and says that:
> lifetime may not live long enough
>
> associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`

But actually the opposite is true: the function was supposed to return data with lifetime `'1` but is returning data with lifetime `'a` because the GAT in question is invariant in `'a`.  You could say that `'1` doesn't live long enough, but in my opinion it would be better to say that `'a` is invariant (and thus doesn't "live short enough").

[Witnessed in this URLO topic by nnotaka.](https://users.rust-lang.org/t/having-trouble-understanding-gat-related-lifetime-issue/90173)

### Other cases

```Rust
// This one gives better diagnostics w.r.t. variance but
// still gets the "supposed to return" lifetimes backwards 
struct Foo2<'a> {
    foo: *mut &'a str,
}

impl<'a> Foo2<'a> {
    fn foo(&self) -> *mut &str {
        self.foo
    }
}

// This contravariant case suggests a bound which is
// effectively invariant, but still gets the lifetimes
// backwards
struct Foo3<'a> {
    foo: &'a dyn Fn(&'a str),
}

impl<'a> Foo3<'a> {
    fn foo<'b>(&'b self) -> &'b dyn Fn(&'b str) {
        self.foo
    }
}
```


### Anything else?

* [Main playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0d03ea1c1e933db07dce1b786e74d4b4)
* [`*mut` playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8df1a6ba114ac03acc6fcd3f59619aae)
   ```rust
   error: lifetime may not live long enough
    --> src/lib.rs:7:9
     |
   5 | impl<'a> Foo2<'a> {
     |      -- lifetime `'a` defined here
   6 |     fn foo(&self) -> *mut &str {
     |            - let's call the lifetime of this reference `'1`
   7 |         self.foo
     |         ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
     |
     = note: requirement occurs because of a mutable pointer to `&str`
     = note: mutable pointers are invariant over their type parameter
     = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
  ```
* [`dyn Fn` playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=280abf36a5603f1eb090dee7fa8dbb16)
   ```
   error: lifetime may not live long enough
    --> src/lib.rs:7:9
     |
   5 | impl<'a> Foo3<'a> {
     |      -- lifetime `'a` defined here
   6 |     fn foo<'b>(&'b self) -> &'b dyn Fn(&'b str) {
     |            -- lifetime `'b` defined here
   7 |         self.foo
     |         ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
     |
     = help: consider adding the following bound: `'b: 'a`
   ```
* [Covariant case where the "return data" lifetimes are correct](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f55deab4e244d845beb98c4d46568531)
   ```
   error: lifetime may not live long enough
    --> src/lib.rs:7:9
     |
   5 | impl<'a> Foo4<'a> {
     |      -- lifetime `'a` defined here
   6 |     fn foo(&self) -> &'a str {
     |            - let's call the lifetime of this reference `'1`
   7 |         self.foo
     |         ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
   ```

@rustbot label +A-lifetimes +A-variance 

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"dianne"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->