Is it possible to avoid the new keyword opaque
, in favor of reusing existing self-type syntax?
Can we allow type ID = Any { this: Long => }
instead of opaque type ID = Long
?
The self-type syntax has an additional advantage: it allows parts of the supertypes or members to be transparent.
type ID = Any { this: Long => }
implicitly[ID <:< AnyVal] // should not compile
type ID2 = AnyVal {
// The actual self-type is `AnyVal { def +(rhs: Long): Long } with Long`,
// which can be proven to be same type of `Long`, when calculating its `glb`
this: Long =>
def +(rhs: Long): Long
}
implicitly[ID2 <:< AnyVal] // should compile
def minus1(id2: ID2): Long = {
id2 - 1L // should not compile.
}
def plus1(id2: ID2): Long = {
id2 + 1L // should compile and should not be a reflective call, because the backend knows `ID2 =:= Long`
}
We can also allow casting a trait
or a class
to its self-type in its companion object for consistency.