Automatic coercions for trait "inheritance"

I've seen quite a few users writing trait FooTrait: Supertrait {} and expecting to be able to cast &dyn FooTrait to &dyn Supertrait.

The answer is that Rust doesn't really have inheritance, …but maybe Rust could be less picky about it?

The current workaround requires manually adding a method to the trait that does the cast for each implementation:

fn as_supertrait(&self) -> &dyn Supertrait

The workaround is not obvious, but also the implementation is a trivial boilerplate. It seems like a great candidate for compiler to do automatically. Probably not literally a named method, but some vtable glue that makes it possible to cast one dyn trait to another.

It's going to be tricky with multiple traits (Foo: Bar + Baz), but lots of languages reject multiple inheritance, so for a start I propose doing it only when there's a single supertrait.

4 Likes

Really? I'd expect it to be trivial.

We know the vtables exist, all we need is for Foo's vtable to store pointers to Bar and Baz's vtables.

A better solution would be have the vtables embedded in the outer vtables for each concrete type.

7 Likes

Either way, my point is that when you write impl Foo for MyFoo, you need it to be legal to convert any MyFoo to either a &dyn Bar or a &dyn Baz, which means the vtables are generated somewhere. All we need is a way is to be able to get the vtable pointers from a &dyn Foo.

2 Likes