Skip to content

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

Open
@tim3z

Description

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<usize>;
    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

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)GATs-triagedIssues using the `generic_associated_types` feature that have been triagedS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions