Rust: downcasting and Box <Any>
pub struct WidgetWrap { // ... widget: RefCell<Box<Any>>, } At some point, I want to drop Box<Any> into Box<WidgetTrait>
let mut cell = widget.borrow_mut(); let w = cell.downcast_mut::<Box<WidgetTrait>>(); This gives me an error of this kind:
error: instantiating a type parameter with an incompatible type `Box<WidgetTrait>`, which does not fulfill `'static` [E0144] What does it mean?
I looked at How to fix it: the value may contain links; add `static` attached to` T` and tried to add + 'static everywhere.
pub struct WidgetWrap { // ... widget: RefCell<Box<Any + 'static>>, } let mut cell = widget.borrow_mut(); let w = cell.downcast_mut::<Box<WidgetTrait + 'static>>(); It fixes compilation errors, but fails when I try to maximize a fallen window, as shown above. And yes, the contents of the field is an object that implements WidgetTrait .
Obviously, I am coding in Rust at a level that I don't quite understand. But maybe someone will help me better understand the concepts involved in the above task.
(I will ignore the 'static part as its comparatively inconsequential for the Im parts explaining.)
Box<Trait> for this Trait attribute is stored as two pieces of data: a pointer to the actual data in memory and a pointer to vtable to implement its Trait types.
From this you can see that you have only one level of traityness - if you have a Box<WidgetTrait> and you set it again as a Box<Any> , you can only get it as a Box<WidgetTrait> object. Similarly, if you take a Widget type that implements WidgetTrait and puts it in a Box<Any> , you can only get it as a Widget object, not as a Box<WidgetTrait> object.
This is the nature of type identifiers that are used domestically: unlike a dynamic or virtual language, a type system is a pure compilation time construct; at run time there is no such system as type.
The solution, if you really need a solution on these lines (you probably shouldn't: stick with just Box<WidgetTrait> , probably the best way) is to have a trait that also implements what Any does. This is currently not the easiest thing, but it can be done. Teepees Header trait - an example of how this can work; a Box<Header> object will have header conversion methods, as well as Any s .downcast_ref() , etc.