struct FF;
impl FF {
fn ff() {}
}
fn ff() {}
let c = &ff as &dyn Any;
let c = c.downcast_ref::<fn()>().unwrap();
/// why does downcat() return None ?
let c = &FF::ff as &dyn Any;
let c = c.downcast_ref::<fn()>().unwrap();
/// return None too
debug_assert!(*c==FF::ff); // compiles Ok
debug_assert!(c==FF::ff); // compiles Error, why ?
&ff is a reference to function item type, which is probably not what you intended. in rust, function pointers and function items are distinct types, but the latter can cocerce to the former. try this instead:
let c = &(ff as fn()) as &dyn Any;
let c = c.downcast_ref::<fn()>().unwrap();
as the compiler suggested, it's a type error.
again, you are probably confused about rust function pointer types and C function pointers. see:
Thanks, you give the right answer. It works. Yes, I am really confused about function usage between rust and C. And I have carefully read the help doc about function item and function pointer.
The important thing to notice is that all function items have distinct types, which are not function pointers (they are ZSTs actually). The reason for this is to allow the compiler to inline functions/use a different calling convention on them, even if they are passed as arguments or something.
But, if you need to, you can cast any of these types to the corresponding function pointer type, which uses a uniform calling convention. In a way, that is already a kind of type erasure.
You can see this here:
The function item types are unnameable, but using some generics, it is possible to refer to them.
So here we can see that it is actually possible to downcast them if you know the original function item type (but at that point it really doesn't make sense to do so):