Description
trait T[A]:
fn f(self)
impl T[I32]: ...
impl[A: T] T[Vec[A]]: ...
# Overlaps with the more general definition above.
impl T[Vec[I32]]: ...
I think this is actually safe when all of the following holds:
-
We do monomorphisation, instead of runtime polymorphism.
This allows compiling call sites:
fn g[A: T](a: A) = [a].f()
Here each call site of
g
will create a monomorphicg
based on the type argument, so I know whichf
to call in[a].f()
, without having to do runtime type tests. -
To make sure (1) covers all invocations of the
f
, the trait is not allowed in trait objects. E.g. you can't have an existential with this trait as the type. -
Specialization is only allowed within the compilation/type checking unit of the trait. Users cannot add implementations that specialize an existing implementation.
This makes sure when two packages/libararies build and run fine on their own, they will build and run the same way when they are linked together in a third package/library.
I actually don't know if this pattern is useful. I'm thinking maybe in the standard library we can provide faster Hash
on Vec[I32]
(and other Vec
types with 4-byte unboxed elements) using this.