HRTB bug when for<'a> Fn(<X as Trait<'a>>::Assoc)?

Am I facing a HRTB bug?

trait Variable<'a> {
    type Type;

impl Variable<'_> for () {
    type Type = ();

fn check<F, T>(f: F)
    F: Fn(T),
    F: for<'a> Fn(<T as Variable<'a>>::Type),
    T: for<'a> Variable<'a>,

fn main() {
    fn fn_test(_: ()) {}



   Compiling playground v0.0.1 (/playground)
error[E0631]: type mismatch in function arguments
  --> src/
18 |     fn fn_test(_: ()) {}
   |     ----------------- found signature of `fn(()) -> _`
19 |     check(fn_test);
   |     ----- ^^^^^^^ expected signature of `for<'a> fn(<() as Variable<'a>>::Type) -> _`
   |     |
   |     required by a bound introduced by this call
note: required by a bound in `check`
  --> src/
9  | fn check<F, T>(f: F)
   |    ----- required by a bound in this
12 |     F: for<'a> Fn(<T as Variable<'a>>::Type),
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`

For more information about this error, try `rustc --explain E0631`.
error: could not compile `playground` due to previous error

HRTB projections strike again?.

Yes, should be a bug; seems to have to do with type inference, too, since the code compiles if you call it as check::<_, ()>(fn_test).

You can also make it compile by changing it to check(|x| fn_test(x)).

Seems to only be buggy with fn items, too. Closures work as in

let fn_test = |x: ()| ();

Edit: Actually, another failure case is

fn blah(fn_test: impl Fn(())) {

The same workarounds work here, too.

Edit2: I feel like this is a different bug than the one @H2CO3 linked.


Thanks for investigating. I'm filing it as a bug!

Edit: reported in #90875


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.