Repository: rust
Issue: Confusing lifetime error on `impl`s involving `self` and ADTs with lifetimes
Labels: A-diagnostics,A-lifetimes,A-borrow-checker,T-compiler,A-suggestion-diagnostics,D-confusing,D-newcomer-roadblock

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

```rust
struct Struct<'a>(&'a ());
struct OtherStruct<'a>(&'a Struct<'a>);
trait Trait<'a> {
    fn foo(&self, x: &str) -> OtherStruct<'a>;
}

impl<'a> OtherStruct<'a> {
    fn new(s: &'a Struct<'a>) -> OtherStruct<'a> {
        OtherStruct(s)
    }
}

impl<'a> Trait<'a> for Struct<'a> {
    fn foo(&self, x: &str) -> OtherStruct<'a> {
        OtherStruct::new(self)
    }
}

impl<'a> Struct<'a> {
    fn foo(&self, x: &str) -> OtherStruct<'a> {
        OtherStruct::new(self)
    }
}
```

[The current output is](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d4fa918aafa9b500cde9d2a0ccbcf16c):

```
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/lib.rs:15:9
   |
15 |         OtherStruct::new(self)
   |         ^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 14:12...
  --> src/lib.rs:14:12
   |
14 |     fn foo(&self, x: &str) -> OtherStruct<'a> {
   |            ^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:15:26
   |
15 |         OtherStruct::new(self)
   |                          ^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 13:6...
  --> src/lib.rs:13:6
   |
13 | impl<'a> Trait<'a> for Struct<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/lib.rs:15:9
   |
15 |         OtherStruct::new(self)
   |         ^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `OtherStruct<'a>`
              found `OtherStruct<'_>`

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/lib.rs:21:9
   |
21 |         OtherStruct::new(self)
   |         ^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 20:12...
  --> src/lib.rs:20:12
   |
20 |     fn foo(&self, x: &str) -> OtherStruct<'a> {
   |            ^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:21:26
   |
21 |         OtherStruct::new(self)
   |                          ^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 19:6...
  --> src/lib.rs:19:6
   |
19 | impl<'a> Struct<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/lib.rs:21:9
   |
21 |         OtherStruct::new(self)
   |         ^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `OtherStruct<'a>`
              found `OtherStruct<'_>`
```

The output could be potentially simplified somewhat, but more importantly, we could relatively easily [suggest that `&self` should be changed to `&'a self`](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=231861fabcd6bbf66e9e10dea133b146). For the `trait` case it is slightly more complex because we somewhat defer to the trait being right, but in this case we should indeed suggest changing both the trait and the impl to be constrained by a lifetime.

_https://twitter.com/KardOnIce/status/1380950591770345474_