Upcasting a boxed trait?

I'm looking for a way to use trait object for a dynamically typed object system.

At first I thought I'd simply use a boxed trait, but I can't make compiler type-check my code when I try to up-cast a boxed child trait to a boxed parent trait

What I'm trying to do is something like the following:

trait ParentTrait {
    fn foo(&self);
}

trait ChildTrait: ParentTrait {
    fn bar(&self);
}

struct ChildImpl;

impl ChildTrait for ChildImpl {
    fn bar(&self) {}
}

impl<T: ChildTrait> ParentTrait for T {
    fn foo(&self) {
        self.bar()
    }
}

fn main() {
    let child_box: Box<ChildTrait> = Box::new(ChildImpl);
    let parent_box: Box<ParentTrait> = child_box as Box<ParentTrait>;
}

The rustc error message requires that some traits to inherit Sized, but if I add such constraint, rustc says the traits are not object-safe.

Is there a way that I can make this work?

There has been some discussion about this exact issue on stackoverflow. The gist is: not possible without additional magic because the ChildTrait vtable has no pointer to the ParentTrait vtable. But it's backwards compatible to be implemented after 1.0

1 Like