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:
- The methods from
SomeTrait
andClone
would be available as inherent methods for instances of typeSomeStruct
. - It would be an error if
SomeStruct
did not implement bothSomeTrait
andClone
elsewhere. - 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:
-
#[repr(thin)]
traits can only be impl’d by types that declare the trait as an inherent trait - 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.