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.

So far 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 the implementation is a trivial boilerplate. It seems like a great candidate for the 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.

If it would be tricky with multiple traits (like Foo: Bar + Baz causing combinatorial explosion of Bar + Baz or Bar or Baz) then I propose doing it only when there's a single supertrait. It wouldn't be a surprising limitation, because lots of languages reject multiple inheritance already.

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

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.