Consider the following code:
#![feature(fn_traits)]
fn test_fn_2_args<F>(f: Box<F>)
where
F: Fn(i32, i64) -> i32
{
<Box<F> as Fn<(i32, i64)>>::call(&f, (1, 2));
}
fn main(){
test_fn_2_args(Box::new(|first, second| {
println!("{first}, {second}");
first
}));
}
This code requires unstable fn_traits, but this is not clear why. As per fn_traits docs it's designed for implementing closure-like type which I don't do in this example.
All I do is interpret Box<Fn> as Fn which is not clear why is allowed as well since Box<Fn> does not implement Fn obviously.
Calling a boxed closure, does not require unstable. To call it, you simply use the standard calling syntax (i.e. a call expression) to call it. Boxed or not.
It doesn't matter whether you have
Fn()orBox<dyn Fn()>you call it in the same way, i.e.f().The reason you can call them in the same way, is because there is a blanket implementation of
impl<F> Fn for Box<F> where F: Fn.The reason you can use
Fn, but notFn::call()is becauseFnis stable, whileFn::call()is unstable. Which as you've discovered is part of the unstablefn_traitsfeature (see issue #29625).So the issue is not "interpreting
Box<Fn>asFn", the issue is you're attempting to call the unstableFn::call().In short, doing this is stable:
While doing the following is unstable:
All in all, just call the closure like any other function:
You don't even need
Box:Again, since there is a blanket implementation of
impl<F> Fn for Box<F> where F: Fn. That also means that changingtest_fn_2_args()to not useBox, still allows you to call it using a boxed closure. So the following compiles perfectly fine.