How can I downcast from Box<Any> to a trait object type?
(I shall ignore the 'static
part as it’s comparatively irrelevant for the parts I’m explaining.)
Box<Trait>
for a given trait Trait
is stored as two pieces of data: a pointer to the actual data in memory and a pointer to the vtable for its type’s implementation of Trait
.
From that, you may see that you can only have one level of traityness—if you have a Box<WidgetTrait>
and you box it again as Box<Any>
, you would only be able to get it out as a Box<WidgetTrait>
object. Similarly, if you take a type Widget
that implements WidgetTrait
and box it in a Box<Any>
, you can only get it out as a Widget
object, not as a Box<WidgetTrait>
object.
Such is the nature of the type IDs being used internally: unlike in a dynamic or VM-based language, the type system is purely a compile-time construct; there is no such thing as the type system at runtime.
The solution, if you really need a solution along these lines (you probably don’t; sticking with just a Box<WidgetTrait>
is probably the best way) is to have a trait which also implements what Any
does. This is not the simplest thing at present, but can be done. Teepee’s Header
trait is an example of how this can work; a Box<Header>
object will have the header-transforming methods as well as Any
’s .downcast_ref()
and so forth.