Repository: rust
Issue: Missing lifetimes needed in `impl` item don't have enough help for newcomer devs
Labels: A-diagnostics,A-lifetimes,T-compiler,A-suggestion-diagnostics,D-newcomer-roadblock,D-invalid-suggestion,D-terse

If you write like

```rust
impl IntoIterator for &S {
    type Item = &T;
    type IntoIter = std::collections::btree_map::Values<i32, T>;
    
    fn into_iter(self) -> Self::IntoIter {
        todo!()
    }
}
```
[you get the following errors](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7b192052b2b1ac8574eb89130b318108)
```
error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
 --> src/main.rs:5:17
  |
5 |     type Item = &T;
  |                 ^ this lifetime must come from the implemented type

error[E0106]: missing lifetime specifier
 --> src/main.rs:6:56
  |
6 |     type IntoIter = std::collections::btree_map::Values<i32, T>;
  |                                                        ^ expected named lifetime parameter
  |
help: consider introducing a named lifetime parameter
  |
6 |     type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>;
  |                  ++++                                       +++
```
ignoring the first one for now, [if you follow the suggestion you get](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=b9eb24218645c31dccc1d5ad1b0939c7)
```
error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration
 --> src/main.rs:6:18
  |
6 |     type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>;
  |                  ^^^^ lifetimes do not match type in trait
```
Both of these cases should instead mention likely adding the lifetime to the `impl` *if* either the trait or the self type have *any* lifetimes, named or anon. We should mention that the `<'a>` should be removed to match the def, and point at the def if local to modify it to add it to the trait.

If we don't add the `<'a>` to the `type IntoIter`, [we get something closer to what we want](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=cbac1193e7340e33472dc6773b6d0db9):

```
error[E0261]: use of undeclared lifetime name `'a`
 --> src/main.rs:6:57
  |
6 |     type IntoIter = std::collections::btree_map::Values<'a, i32, T>;
  |                                                         ^^ undeclared lifetime
  |
help: consider introducing lifetime `'a` here
  |
6 |     type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>;
  |                  ++++
help: consider introducing lifetime `'a` here
  |
4 | impl<'a> IntoIterator for &S {
  |     ++++
```

We shouldn't be suggesting modifying `type IntoIter` if we can know that the trait definition didn't have named lifetimes.

If we add `impl<'a>`, then [we get a very terse output](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=6bed38a375e923b8b5a8f8272b6f0212):

```
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
 --> src/main.rs:4:6
  |
4 | impl<'a> IntoIterator for &S {
  |      ^^ unconstrained lifetime parameter
```

This should look at the trait and self type and see if there is any anon lifetime at play, and suggest using the named lifetime there. In this case, `&'a S`.

In all of these cases we still get:

```
error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
 --> src/main.rs:5:17
  |
5 |     type Item = &T;
  |                 ^ this lifetime must come from the implemented type
```

When `impl` has lifetimes, the above should suggest using that lifetime.

Currently the documentation of [`E0261`](https://doc.rust-lang.org/error_codes/E0261.html) mentions a similar enough case, but [`E0207`](https://doc.rust-lang.org/error_codes/E0207.html) doesn't. We'd likely want to add a mention about lifetimes in the latter.

_Inspired by https://github.com/mainmatter/100-exercises-to-learn-rust/issues/245_

---

- [ ] on `type NoLt = TypeMissingLt;`, do not suggest `type NoLt<'a> = TypeMisingLt<'a>;` if the trait doesn't accept it
- [ ] on `type NoLt = TypeMissingLt;`, suggest adding a lifetime to the `impl` if the trait or self type have anon lifetimes
- [ ] on `type NoLt<'a> = TypeMissingLt<'a>;`, suggest removing the lifetime from the `type` if the `impl` has a named lifetime
- [ ] on `type NoLt = TypeMissingLt<'a>;`, suggest adding `'a` to the `impl` if the trait or self type have anon lifetimes
- [ ] on `impl<'a> IntoIterator for &S`, suggest changing the self type to `&'a S`
- [ ] on `type NoLt = &T;`, if `impl` has a lifetime suggest using that
- [ ] on `type NoLt = &T;`, suggest using a named lifetime from the `impl` if present
- [ ] on `type NoLt = &T;`, suggest adding `'a` to the `impl` if the trait or self type have anon lifetimes
- [x] expand the documentation of `E0207` to mention these cases