How to use a closure in generic context?

I'm having some trouble trying to get a closure to match a generic parameter, and can't figure out what I'm doing wrong... Any ideas?

error[E0308]: mismatched types
  --> <anon>:25:28
   |
25 | 		QueryWriter::new(writer, |_| true)
   | 		                         ^^^^^^^^ expected type parameter, found closure
   |
   = note: expected type `F`
              found type `[closure@<anon>:25:28: 25:36]`

This implementation means "for any F implementing Fn(Message) -> bool, implement From<W> for QueryWriter<W>, but you're trying to use a specific F.

1 Like

To clarify, you are saying that your function returns any Fn(Message) -> bool, where the exact type is decided by user of a function, which is obviously not true - your function only returns a single possible function |_| true.

Instead, don't use generic type parameters. Function pointer will do, although it will prevent you from using closures (as each closure is its own unnameable type).

impl<W> From<W> for QueryWriter<W, fn(Message) -> bool>
    where W: Trace
{
    fn from(writer: W) -> Self {
        fn always_true(_: Message) -> bool {
            true
        }
        QueryWriter::new(writer, always_true)
    }
}

This however does have a cost of storing function pointer, so it's clearly a workaround.

2 Likes

Ah, right, that makes sense. Is a bit of a frustrating error message, though. Thanks for your help.

Perhaps @skysch can define QueryWriter as a trait and then have two separate impls, one where caller supplies the predicate and the other where no predicate is stored.

I'm not sure how that would work with From. It's probably not viable for the purpose of this thing anyway, which is to be a stateful wrapper around a Write implementor, so I'm perfectly happy storing the function pointer in the object.

You'd use a different From. Here's a sketch: Rust Playground