Reputation: 34403
Following code does not compile with Scala 2 (tested 2.13.7 and Scala 2.12.15):
trait AttributeBase
trait Attribute extends AttributeBase {
def name: String
}
trait Base {
def attribute: AttributeBase
}
trait Derived { self: Base =>
def attribute: Attribute
def name = attribute.name
}
The code compiles fine with Scala 3. With Scala 2 the error is:
value name is not a member of AttributeBase
It compiles fine when extends
is used instead of a self type:
trait Derived extends Base {
Another possible workaround is:
def name = (this:Derived).attribute.name
Why is the type of Derived.attributed
assumed to be AttributeBase
and not Attribute
? Is this a Scala compiler bug, or some Scala 2 limitation?
Upvotes: 4
Views: 84
Reputation: 27535
I'd say it would be a bug or at least a difference between 2 and 3 in interpreting self-types. Here:
trait Derived { self: Base =>
def attribute: Attribute
}
you are doing 2 things
this
should be treated as Base
(which defines attribute
as AttributeBase
attribute
as Attribute
So which takes the precedence?
In Scala 2.13 specification I wasn't able to to pinpoint the definition of a self-type, AFAIK it only exists in syntax summary as SelfType
or in changelogs. It seems it just an informal way of calling a type-ascription on (possibly aliased) this
(following all the normal rules about type ascription and type definitions, so no special treatment, so no need to address it explicitly). If so, it might follow what we read in Tour of Scala about self-types - self: Tpe =>
does a sort of casting (narrowing) of this
into Tpe
from the POV of all the definitions inside, but at the same time allows adding new and specializing existing definitions (so 2.13 is kind of inconsistent as you noticed).
It seems that Scala 3 has it better sorted out as it seemingly treat it as a type-bound instead of a (selective) type-cast (which makes sense considering that Scala 3 implements DOT calculus and tries to remove inconsistencies and ambiguities). However, I wasn't able to find an exact statement on self-types in specification either so I would say that this improvement might be "just" a side effect of following the better formalism.
Upvotes: 3