aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-16 22:29:27 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:02:03 +0200
commit7c56a5bb3d0b7902dbee6f11788e2d1033b20873 (patch)
tree7eefad0b72c8cb8ecb3e159386cf4c5fed0fdb4a /src/dotty/tools/dotc/core/Types.scala
parent37c6e42cfd04c62c504a9143cb2cc4b500baf38b (diff)
downloaddotty-7c56a5bb3d0b7902dbee6f11788e2d1033b20873.tar.gz
dotty-7c56a5bb3d0b7902dbee6f11788e2d1033b20873.tar.bz2
dotty-7c56a5bb3d0b7902dbee6f11788e2d1033b20873.zip
Make self types always include a reference to the class
In a situation like class C { this: D => } the effective self type of the class is taken to be D & C. Why? First, Scala 2.x does it that way. Second, it's needed to make the FullParameterization transform go though.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 89bef109b..289515ae1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2030,19 +2030,31 @@ object Types {
decls: Scope,
selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType {
- def selfType(implicit ctx: Context): Type = selfInfo match {
- case NoType =>
- if (selfTypeCache == null) selfTypeCache = computeSelfType(cls.typeRef, cls.typeParams)
- selfTypeCache
- case tp: Type => tp
- case self: Symbol => self.info
+ /** The self type of a class is the conjunction of
+ * - the explicit self type if given (or the info of a given self symbol), and
+ * - the fully applied reference to the class itself.
+ */
+ def selfType(implicit ctx: Context): Type = {
+ if (selfTypeCache == null) {
+ def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
+ selfTypeCache = selfInfo match {
+ case NoType =>
+ fullRef
+ case tp: Type =>
+ if (cls is Module) tp else AndType(tp, fullRef)
+ case self: Symbol =>
+ assert(!(cls is Module))
+ AndType(self.info, fullRef)
+ }
+ }
+ selfTypeCache
}
private var selfTypeCache: Type = null
- private def computeSelfType(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
+ private def fullyAppliedRef(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
case tparam :: tparams1 =>
- computeSelfType(
+ fullyAppliedRef(
RefinedType(base, tparam.name, TypeRef(cls.thisType, tparam).toBounds(tparam)),
tparams1)
case nil =>