tl;dr: You must be explicit in your definitions when adding type info. Instead of Fn, which is a trait, you should use fn, which is a type.
I am not a black Rust mage though, so here is what I did to find out what's wrong: First, I took the liberty to simplify the situation to a point which works:
pub trait Message{}
struct MyMessage;
impl Message for MyMessage {}
pub fn my_fun<Req, F>(_f: F) -> Result<Vec<u8>, String>
where
Req: Message,
F: (FnOnce(&Req) -> Result<Req, String>),
{
unimplemented!();
}
pub fn main() {
let _ = my_fun(|_message: &MyMessage| { unimplemented!(); });
}
It's basically what you already have, sans the Box and the additional variable. Just passing the closure will handle it inline, so the compiler will do the thinking about how to handle sizing internally. Great. Let's get the closure in a variable, shall we!
pub fn main() {
let router = |_message: &MyMessage| { unimplemented!(); };
let _ = my_fun(router);
}
This code will compile, too. What magic did I do??? Simple. I remembered that the Rust compiler is very clever, so it will figure out the variable type on its own, just like before when I left out the variable. The lesson here: Everything's ok, however you declared the wrong type and traits explicitly, which made it impossible for the compiler to figure out the size. What would be the correct type signature, then, you ask? I am using IntelliJ, so I cheated a bit, because I get the type displayed implicitely, however the explicit code looks like this:
pub fn main() {
let router: fn(&MyMessage) -> Result<MyMessage, String> = |_message: &MyMessage| { unimplemented!(); };
let _ = my_fun(router);
}
which you can also write as
pub fn main() {
let router: fn(&MyMessage) -> Result<MyMessage, String>;
router = |_message: &MyMessage| { unimplemented!(); };
let _ = my_fun(router);
}
I'd say, it's one of those instances, when Rust is a bit annoying. In the function you declared that the parameter should implement the trait Fn, however, in the definition, you actually must be explicit. A trait does not have a size, however a type does! And which primitive type is used for functions? Right! fn. Check out Fn vs fn for more info on them.