use std::rc::Rc;
use core::any::Any;
pub trait AnimalT {}
fn foo (ptr: Rc<Any>) -> Option<Rc<AnimalT>> {
ptr.downcast::<AnimalT>().ok()
}
gets error:
error: the `downcast` method cannot be invoked on a trait object
--> src/lib.rs:10:9
|
10 | ptr.downcast::<AnimalT>().ok()
| ^^^^^^^^
error: aborting due to previous error; 3 warnings emitted
error: could not compile `playground`.
Is Rc<Any> -> Option<Rc<AnimalT>> possible at all?
No you can't. Traits are not type, they're abstract behavior shared between types. dyn Trait is a dynamically sized type whose reference also holds a ptr to the type-specific vtable which contains the function pointers for the trait.
Problem is, there's no way to get the vtable ptr of trait AnimalT from the dyn Any type. dyn Any's vtable holds a type id of the underlying concrete type, which is a hash. You can get the type id from the concrete type and compare it with the one from dyn Any, but you can't get type from the type id.
When you control the parent trait it is possible, but you can't automate implementing maybe_dog. Every implementor of AnimalT must have a separate implementation of maybe_dog.
Generally, Rc arguments are owned, rather than passed as a reference. If you make that change, your code will compile but not behave as you expect (per @alice's comment).
It is possible to define a helper macro to make the individual implementations easier, though: