I am trying to implement a trait for all function pointers. I've tried to do this by both implementing the trait for fn()
as well as F: Fn()
but am running into limitations with both options.
A simplified example is:
trait A { }
trait C { }
impl A for fn() { }
impl A for &fn() { }
impl<P> A for fn(&P) { }
impl<P> A for &fn(&P) { }
impl<F> C for F where F: Fn() { }
// impl<F, P> C for F where F: Fn(&P) { } -- unconstrained type parameter
fn my_func() { }
fn my_func_with_p(_: &usize) { }
fn accept_a<F: A>(_: &F) { }
fn accept_dyn_a(_: &dyn A) { }
fn accept_c<F: C>(_: &F) { }
fn accept_dyn_c(_: &dyn C) { }
fn main() {
accept_a(&(my_func as fn()));
accept_a(&(my_func_with_p as fn(&usize)));
// accept_dyn_a(&my_func); -- trait bound not satisfied
accept_c(&my_func);
accept_dyn_c(&my_func);
}
And the playground is available at: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=889ed167fbd2dad717b6e6a63a178764
- If I implement the trait for
fn()
I have to cast the value, and can't use it as an argument for a parameter of&dyn A
. - If I implement the trait for
Fn()
, I don't have to worry about casting the value and can use it as&dyn C
, but can't implement it for functions with an argument since the type parameter is unconstrained.
Am I doing something wrong and/or missing some alternative option?