Repository: rust
Issue: confusing error: "expected associated type" and "found associated type" are the same in some cases with Fn traits
Labels: A-diagnostics,A-lifetimes,A-closures,T-compiler,D-confusing,D-terse

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: [play](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=use%20std%3A%3Aops%3A%3ANot%3B%0A%0Afn%20compose_mut%3CA%2C%20B%2C%20C%2C%20G%2C%20F%3E(mut%20f%3A%20F%2C%20mut%20g%3A%20G)%20-%3E%20impl%20FnMut(A)%20-%3E%20C%0Awhere%0A%20%20%20%20F%3A%20FnMut(A)%20-%3E%20B%2C%0A%20%20%20%20G%3A%20FnMut(B)%20-%3E%20C%2C%0A%7B%0A%20%20%20%20move%20%7Cx%7C%20g(f(x))%0A%7D%0A%0Afn%20predicate(n%3A%20%26usize)%20-%3E%20bool%20%7B%0A%20%20%20%20*n%20%3D%3D%200%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20let%20b%3A%20%26dyn%20FnMut(%26usize)%20-%3E%20bool%20%3D%0A%20%20%20%20%20%20%20%20%26compose_mut(predicate%2C%20bool%3A%3Anot)%3B%0A%20%20%20%20println!(%22ok%22)%0A%7D%0A)

```rust
use std::ops::Not;

fn compose_mut<A, B, C, G, F>(mut f: F, mut g: G) -> impl FnMut(A) -> C
where
    F: FnMut(A) -> B,
    G: FnMut(B) -> C,
{
    move |x| g(f(x))
}

fn predicate(n: &usize) -> bool {
    *n == 0
}

fn main() {
    let b: &dyn FnMut(&usize) -> bool =
        &compose_mut(predicate, bool::not);
    println!("ok")
}

```

The current output is:

```
error[E0308]: mismatched types
  --> src/main.rs:17:9
   |
3  | fn compose_mut<A, B, C, G, F>(mut f: F, mut g: G) -> impl FnMut(A) -> C
   |                                                      ------------------
   |                                                      |
   |                                                      the expected opaque type
   |                                                      the found opaque type
...
17 |         &compose_mut(predicate, bool::not);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected associated type `<impl FnMut<(&usize,)> as FnOnce<(&usize,)>>::Output`
              found associated type `<impl FnMut<(&usize,)> as FnOnce<(&usize,)>>::Output`

```

<!-- The following is not always necessary. -->

I don't understand the issue. This part is especially confusing, because both types are the same:
```
   = note: expected associated type `<impl FnMut<(&usize,)> as FnOnce<(&usize,)>>::Output`
              found associated type `<impl FnMut<(&usize,)> as FnOnce<(&usize,)>>::Output`
```

I think this has to do with the Fn traits, because it doesn't happen with any other trait, so this code compiles:

```rust
trait T {}

struct S;

impl T for S {}

fn return_impl() -> impl T {
    S
}

fn main() {
    let b: &dyn T =
        &return_impl();
    println!("ok")
}
```

Issue exists in both rustc 1.57.0 (f1edd0429 2021-11-29) and rustc 1.59.0-nightly (0b42deacc 2021-12-09).