Repository: rust
Issue: GAT: mismatched types [E0308]
Labels: I-ICE,T-compiler,GATs-triaged,fixed-by-next-solver,A-GATs

The following program is failing to compile on nightly ([Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=a7464fd2b8d9e352b704fda4e297ccb2)):
```rust
#![feature(generic_associated_types)]
#![allow(type_alias_bounds)]

use once_cell::sync::Lazy;
use std::collections::HashMap;

// ============= generic code =============

trait Provider: Sized {
    // IterateCb's iterator item.
    type ListEntry<'a>: std::fmt::Debug;

    // Load IterateCb callbacks.
    fn load_callbacks() -> Callbacks<Self>;
}

type IterateCb<P: Provider> = for<'a> fn(&'a P) -> Box<dyn Iterator<Item = P::ListEntry<'a>> + 'a>;

struct Callbacks<P: Provider>(HashMap<&'static str, IterateCb<P>>);

// ============ implementation ============

// Global callbacks.
static CALLBACKS: Lazy<Callbacks<Instance>> = Lazy::new(Instance::load_callbacks);

struct Instance {
    peers: Vec<Peer>,
    routes: Vec<Route>,
}

#[derive(Debug)]
struct Peer(i32);

#[derive(Debug)]
struct Route(i32);

#[derive(Debug)]
enum InstanceListEntry<'a> {
    Peer(&'a Peer),
    Route(&'a Route),
}

impl Provider for Instance {
    type ListEntry<'a> = InstanceListEntry<'a>;

    fn load_callbacks() -> Callbacks<Self> {
        let mut callbacks = HashMap::new();

        // First callback.
        let callback: IterateCb<Self> = |instance| {
            let iter = instance.peers.iter().map(InstanceListEntry::Peer);
            Box::new(iter)
        };
        callbacks.insert("peers", callback);

        // Second callback.
        let callback: IterateCb<Self> = |instance| {
            let iter = instance.routes.iter().map(InstanceListEntry::Route);
            Box::new(iter)
        };
        callbacks.insert("routes", callback);

        // todo!();
        Callbacks(callbacks)
    }
}

fn main() {
    // Initialize instance.
    let instance = Instance {
        peers: vec![Peer(1), Peer(2)],
        routes: vec![Route(1), Route(2)],
    };

    // Print peers.
    if let Some(cb) = CALLBACKS.0.get("peers") {
        let list_iter = (*cb)(&instance);
        for list_entry in list_iter {
            println!("peer: {:?}", list_entry);
        }
    }
    // Print routes.
    if let Some(cb) = CALLBACKS.0.get("routes") {
        let list_iter = (*cb)(&instance);
        for list_entry in list_iter {
            println!("route: {:?}", list_entry);
        }
    }
}
```

In this program, I have a global list of callbacks that return an iterator over a generic associated type (`Provider::ListEntry<'a>`). The lifetime parameter is necessary because the associated type needs to be an enum of references.

Unfortunately the code isn't compiling, and the error message doesn't seem to make much sense:
```
# cargo check
    Checking hello_cargo v0.1.0 (/mnt/renato/git/rust/hello_cargo)
error[E0308]: mismatched types
  --> src/main.rs:64:19
   |
64 |         Callbacks(callbacks)
   |                   ^^^^^^^^^ expected associated type, found enum `InstanceListEntry`
   |
   = note: expected struct `HashMap<&'static str, for<'a> fn(&'a Instance) -> Box<(dyn Iterator<for<'a> Item = <Instance as Provider>::ListEntry<'a>> + 'a)>>`
              found struct `HashMap<&str, for<'a> fn(&'a Instance) -> Box<(dyn Iterator<for<'a> Item = InstanceListEntry<'a>> + 'a)>>`
   = help: consider constraining the associated type `<Instance as Provider>::ListEntry<'a>` to `InstanceListEntry<'_>` or calling a method that returns `<Instance as Provider>::ListEntry<'a>`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

For more information about this error, try `rustc --explain E0308`.
error: could not compile `hello_cargo` due to previous error
```

Workaround to make rustc accept the program: https://users.rust-lang.org/t/mismatched-types-gat-compiler-bug/68952/2

### Meta

```
# rustc --version --verbose
rustc 1.60.0-nightly (1bd4fdc94 2022-01-12)
binary: rustc
commit-hash: 1bd4fdc943513e1004f498bbf289279c9784fc6f
commit-date: 2022-01-12
host: x86_64-unknown-linux-gnu
release: 1.60.0-nightly
LLVM version: 13.0.0
```