Very interesting question! I am pretty sure that this is impossible.
Rust shotguns work as monomorphizing functions. This means that the Rust compiler will generate machine function code for each particular type with which the function is called. With one function call, the general parameters are fixed. Therefore, since you call test exactly once in main , the general parameters are fixed for this call.
This means that the type of closure is fixed and that the input parameter of the closure also has a specific type. The compiler displays all types for us, but if we try to annotate them, we quickly notice that we are facing the same problem as the compiler:
test::<_, usize>
This is very similar to the use case for higher type types and general closures. Both of these features are not yet available in Rust AFAIK.
However, you can still achieve what you want using dynamic dispatch:
fn test<F, I: Debug>(gen: F) where F: Fn(fn(Box<Debug>) -> Box<Debug>) -> I { fn input(x: Box<Debug>) -> Box<Debug> { x } println!("{:?}", gen(input)); } fn main() { test(|input| { input(Box::new(10)); input(Box::new(10.0)) }); }
Of course, this is not as good as the general version, but at least it works. Also: if you really don't need ownership in input , you can change Box<Debug> to &Debug .
source share