Repository: rust
Issue: Redundant error for "implementation ... not general enough" in "NLL" mode / since 1.63 (when it was made permanent).
Labels: A-diagnostics,A-lifetimes,A-borrow-checker,T-compiler,D-verbose

This is a classic demonstration of the limitations of ("early-bound") generics wrt HRTB:
```rust
fn type_generic<T>(_: T) {}

struct LtGen<'a>(&'a ());
fn takes_ltgen_forall_lifetimes(_: impl for<'x> FnOnce(LtGen<'x>)) {}

fn main() {
    takes_ltgen_forall_lifetimes(type_generic);
}
```
<sup>(I don't know what issue we have open about it - #30904 is too specific, there must be one about generic functions - and also if we ever fix this it will likely require `for<'x> typeof(type_generic::<LtGen<'x>>)` function types, which I've brought up to @nikomatsakis before but I haven't seen any other discussion of)</sup>

Either way, *for now*, the above *should* error (if you're curious, the simplest fix is to use a closure, that itself can be `for<'x>`, and which calls the function, like `|x| type_generic(x)`).

And for a long time (since MIR borrowck?) we've had this error:
```
error: implementation of `FnOnce` is not general enough
 --> <source>:7:5
  |
7 |     takes_ltgen_forall_lifetimes(type_generic);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
  |
  = note: `fn(LtGen<'2>) {type_generic::<LtGen<'2>>}` must implement `FnOnce<(LtGen<'1>,)>`, for any lifetime `'1`...
  = note: ...but it actually implements `FnOnce<(LtGen<'2>,)>`, for some specific lifetime `'2`
```
It's not *perfect*, but it shows the difference between some inferred lifetime (`'2`) and the HRTB (`'1`).

<hr/>

*However*, since 1.63.0 (see comparison on godbolt: https://godbolt.org/z/EzjPzE7xs), we *also* get:
```
error[E0308]: mismatched types
 --> <source>:7:5
  |
7 |     takes_ltgen_forall_lifetimes(type_generic);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
  |
  = note: expected trait `for<'x> FnOnce<(LtGen<'x>,)>`
             found trait `FnOnce<(LtGen<'_>,)>`
note: the lifetime requirement is introduced here
 --> <source>:4:41
  |
4 | fn takes_ltgen_forall_lifetimes(_: impl for<'x> FnOnce(LtGen<'x>)) {}
  |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
```

This is a weirder error, that I naively assumed would be the old regionck (but that got removed, right? so it can't be that), though I suppose it could be some generic obligation solving from inside MIR borrowck.

* it's presented as a type mismatch when it's an unsatisfied bound specifically because of HRTB
* `'_` is used for lifetime inference variables
* can use the ugly `for<'r>` auto-naming in the printout (not here because I wrote `for<'x>`)
* it's not necessary because the better error *is still* being emitted
  * (though I would still make this one `delay_span_bug` if they're not emitted from exactly the same place)

<hr/>

**EDIT**: more information found since opening the issue (in https://github.com/rust-lang/rust/issues/100742#issuecomment-1220394302):
* bisected to #95565
* what I'm calling the "good" error [replaced the "bad" one back in 1.52.0](https://godbolt.org/z/z5qeecKb1)

**EDIT2**: better timeline in https://github.com/rust-lang/rust/issues/100742#issuecomment-1220467532 - the error was improved back in #81972 but the "bonus error" comes from "NLL mode" - e.g. https://github.com/rust-lang/rust/issues/57374#issuecomment-1085201944.

<hr/>

cc @estebank @rust-lang/wg-nll @lcnr (this may be subtle in nature, hopefully someone knows what happened)

cc @Manishearth (who has a similar error though unlikely related to this 1.62.0->1.63.0 change, since [it's on 1.61.0 instead](https://github.com/Manishearth/icu4x/blob/tmp-error-share/rust-toolchain), and does not even have the good error showing up at all - that one still needs to be reduced)