Repository: rust
Issue: Inferred closure argument lifetime is too specific; we should suggest annotating the type to use the more general lifetime
Labels: A-diagnostics,T-compiler

... also the diagnostic repeats for different lifetimes unhelpfully; it appears to be identical until very close inspection.

Given the following code: [[playground]](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2e75228ef27080e0ed5fe1c8f760819c)

```rust
use std::fmt;

pub struct Test;

impl Test {
    fn render_impl(&self, _: &mut impl fmt::Write) -> fmt::Result {
        Ok(())
    }

    pub fn render(&self) -> impl '_ + fmt::Display {
        struct Display<F>(F);
        impl<F> fmt::Display for Display<F>
        where
            F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
        {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                (self.0)(f)
            }
        }

        // okay:
        // Display(move |f: &mut fmt::Formatter<'_>| self.render_impl(f))
        // not okay:
        Display(move |f| self.render_impl(f))
    }
}
```

The current output is:

```
error: implementation of `FnOnce` is not general enough
  --> src/lib.rs:24:9
   |
24 |         Display(move |f| self.render_impl(f))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
   |
   = note: closure with signature `fn(&'2 mut Formatter<'_>) -> Result<(), std::fmt::Error>` must implement `FnOnce<(&'1 mut Formatter<'_>,)>`, for any lifetime `'1`...
   = note: ...but it actually implements `FnOnce<(&'2 mut Formatter<'_>,)>`, for some specific lifetime `'2`

error: implementation of `FnOnce` is not general enough
  --> src/lib.rs:24:9
   |
24 |         Display(move |f| self.render_impl(f))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
   |
   = note: closure with signature `fn(&mut Formatter<'2>) -> Result<(), std::fmt::Error>` must implement `FnOnce<(&mut Formatter<'1>,)>`, for any lifetime `'1`...
   = note: ...but it actually implements `FnOnce<(&mut Formatter<'2>,)>`, for some specific lifetime `'2`

error[E0308]: mismatched types
  --> src/lib.rs:24:9
   |
24 |         Display(move |f| self.render_impl(f))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'r, 's> Fn<(&'r mut Formatter<'s>,)>`
              found trait `Fn<(&mut Formatter<'_>,)>`
note: this closure does not fulfill the lifetime requirements
  --> src/lib.rs:24:17
   |
24 |         Display(move |f| self.render_impl(f))
   |                 ^^^^^^^^
```

Ideally the output should look like:

```
error: closure is not general enough
  --> src/lib.rs:24:17
   |
24 |         Display(move |f| self.render_impl(f))
   |                 ^^^^^^^^ closure is not general enough
   |
   = note: closure with signature `fn(&mut Formatter<'_>) -> _` must implement `Fn(&'1 mut Formatter<'2>) -> _`, for any lifetimes `'1`, `'2`...
   = note: ...but it actually implements `Fn(&'3 mut Formatter<'4>) -> _`, for some specific lifetimes `'3`, `'4`
help: try annotating the closure argument type
  --> src/lib.rs:24:17
   |
24 |         Display(move |f: &mut Formatter<'_>| self.render_impl(f))
   |                        ++++++++++++++++++++
```