Blog post: specialize to reuse (a pre-RFC for "efficient inheritance")

I wanted to note one twist on @aturon’s original idea. One of the things I find somewhat…surprising about a #[repr(thin)] trait declaration is that “thin-ness” is a property of both the trait and the implementing type. That is, if you implement a #[repr(thin)] trait, it affects the layout of your struct, since we must insert a vtable. It feels a bit surprising somehow that this results just from implementing a #[repr(thin)] trait.

Orthogonally, there has long been a desire for “inherent traits” – that is, traits whose methods act like inherent methods for the purpose of method lookup, so that if I want to call a trait method bar on an instance foo of a type Foo, I would do not need the trait imported, I can just do foo.bar(). This would allow for, among other things, migrating from inherent methods to trait methods without duplication. The problem is that these inherent traits need to be declared alongside Foo.

In some earlier thoughts (which were similar to what @aturon described), I was considering killing both those two birds by saying that structs could declare a set of bounds that are exactly the same as the bounds on a type parameter or trait, meaning that they can include both other structs (as @aturon described) as well as traits. These traits would be called the inherent traits of a struct:

struct SomeStruct: SomeTrait + Clone { 
}

#[repr(thin)]
trait SomeTrait { }

As a result of a declaration like the one above, three things would happen:

  1. The methods from SomeTrait and Clone would be available as inherent methods for instances of type SomeStruct.
  2. It would be an error if SomeStruct did not implement both SomeTrait and Clone elsewhere.
  3. Because there are thin trait(s) included in the inherent bounds of SomeStruct, its layout is modified to include an extra vtable.

The rules on #[repr(thin)] traits would be as follows:

  1. #[repr(thin)] traits can only be impl’d by types that declare the trait as an inherent trait
  2. In any list of bounds, all #[repr(thin)] traits must form a hierarchy, so that we can layout the vtables in a simple way.

Anyway, I’m still trying to formulate my full thoughts here, but I wanted to toss this idea out there.