You have ownership over a generic closure (i.e., what it captures), but it may itself be borrowing a local.
For instance, imagine someone calling toAbc with:
let s = String::from("Hello, World!");
let f = |&n: &i32| {
println!("Closure that captures `&s = {:?}` was called with arg `{}`", &s, n);
};
// we give ownership of `f` to `toAbc()`, but:
// - `f` does not own `s`,
// - `f` is borrowing from a local,
// - the type of `f` is not `'static`.
let abc = toAbc(42, f);
drop(s);
(abc.f)(&abc.value); // Use after free!
To be able to have a Box<dyn Fn(...) -> _>, you cannot be borrowing from a local, which is expressed by a : 'static bound on the generic type parameter, or a + 'static bound on the impl ... implicit generic type parameter:
fn toAbc(value: i32, f: impl 'static + Fn(&i32)) -> Abc {
Abc {
value,
f: Box::new(f),
}
}
// or
fn toAbc<F> (value: i32, f: F) -> Abc
where
F : 'static, // captured environment does not borrow a local
F : Fn(&'_ i32), // captured environment is "Callable" (by shared ref)
{
Abc {
value,
f: Box::new(f),
}
}