Rustc cannot infer closure parameter in basic usage

I was very confused by a type inference failure on a very simple closure. Rustc rejects the form where the closure is passed as a variable, but accepts the form where the closure is directly inline in the call. As a novice, this seems super inconsistent. Why should the variable binding affect anything?

fn test() {
    // We does this fail to compile???
    let foobar = |f| {
        let _ = f.baz();
    };

    bar(foobar);

    // But moving the closure into position works?
    bar(|f| {
        let _ = f.baz();
    });
}

struct Foo {}
impl Foo {
    fn baz(&self) -> u32 {
        todo!()
    }
}

pub fn bar(callback: impl Fn(Foo)) {
    todo!()
}

Is there some way I can craft the receiver type so that passing in the closure as a variable works?

To me, this seems like a bug, but I might be wrong.

A longstanding shortcoming of inference.

I don't think it's the variable binding that inhibits inference so much as the context of the call to bar that aids it; bar's parameter type points the way to Foo. Annotating foobar as fn(Foo) works just as well (as does just giving f the type directly, as per the hint).

My interpretation is that it's trying and failing to infer the type before it considers the call to bar (or else it would succeed for the same reason inlining it does). If so I doubt changing bar is going to do anything. But I'm also not a rustc dev.

Is there a reason you can't annotate at the closure definition site? E.g. is the type unnameable in your actual use case for some reason?

It's a feature request and not a bug, unless it used to work -- given the 7+ year old issue, I'm guessing it never has. It is somewhat surprising.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.