Add trait objects with static dispatch

Devirtualization is in fact an optimization that compilers apply today. I believe these passes typically only apply when devirtualizing a single virtualized implementation, and not a set of possible implementations, but if optimizers don't do the latter, they can theoretically be taught how and when to do so.

This feature has been discussed before, typically as enum impl Trait. I believe it's only been proposed in return position before, but it would theoretically be usable anywhere that impl Trait is (and rather than erroring with conflicting defining uses, those defining uses would define the variants).

The interesting note is that operationally, enum impl Trait is a stack form of dyn Trait. You can even imagine implementing it such that the discriminant is the vtable pointer. With a good devirtualization optimizer[1], the main functional difference now is that enum impl Trait has a statically known and automatically inferred size/align, whereas dyn Trait is unsized.

You can close the gap a little more with e.g. Box<dyn Trait, InlineStorage<[usize; 7]>>, but this still requires the programmer specifying a size/align rather than inferring it.

Personally, I'd rather see inline dyn Trait and improved devirtualization before enum impl Trait/static Trait.


  1. Obviously there'd be performance implications and reliability of optimizations and all that; I'm concerning myself more with the operational language design angle than the optimal codegen angle, though both are worth effort. Also, the ability to niche enum impl Trait's discriminant to less than a full usize can be valuable. ↩︎

5 Likes