Wrong (?) [E0631] signature mismatch for function with Fn trait arguments with GAT arguments (original) (raw)

Compiling this code

#![feature(generic_associated_types)]

trait Iterable { type Iterator<'a>; fn iter(&self) -> Self::Iterator<'_>; }

struct SomeImplementation();

impl Iterable for SomeImplementation { type Iterator<'a> = std::iter::Empty; fn iter(&self) -> Self::Iterator<'_> { std::iter::empty() } }

fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { f(&mut i.iter()); }

fn main() { do_something(SomeImplementation(), |_| ()); do_something(SomeImplementation(), test); }

fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}

with the current nightly (rustc 1.56.0-nightly (0afc20860 2021-08-25)) yields an E0631 argument mismatch for both calls to do_something.

error[E0631]: type mismatch in closure arguments
  --> src/main.rs:22:5
   |
22 |     do_something(SomeImplementation(), |_| ());
   |     ^^^^^^^^^^^^                       ------ found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
   |     |
   |     expected signature of `for<'r, 'a> fn(&'r mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
   |
note: required by a bound in `do_something`
  --> src/main.rs:17:48
   |
17 | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`

error[E0631]: type mismatch in function arguments
  --> src/main.rs:23:40
   |
23 |     do_something(SomeImplementation(), test);
   |                                        ^^^^ expected signature of `for<'a> fn(&mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
...
26 | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
   | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
   |
note: required by a bound in `do_something`
  --> src/main.rs:17:56
   |
17 | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=bda4ab05c4a579ec83ab7a0d899f34c1

I expected both calls to compile and from looking at the errors I also see no reasons why the signatures should be incompatible. In the case that my expectation is wrong I would expect the compiler to give me some hint, why this is not possible.

Sorry for the double post, I accidentally used the wrong template in #88355