Skip to content

confusing error: "expected associated type" and "found associated type" are the same in some cases with Fn traits #91829

Open
@jendrikw

Description

Given the following code: play

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`

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:

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 (f1edd04 2021-11-29) and rustc 1.59.0-nightly (0b42dea 2021-12-09).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsD-confusingDiagnostics: Confusing error or lint that should be reworked.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions