diff options
author | Martin Odersky <odersky@gmail.com> | 2014-07-16 22:29:27 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-07-17 11:02:03 +0200 |
commit | 7c56a5bb3d0b7902dbee6f11788e2d1033b20873 (patch) | |
tree | 7eefad0b72c8cb8ecb3e159386cf4c5fed0fdb4a | |
parent | 37c6e42cfd04c62c504a9143cb2cc4b500baf38b (diff) | |
download | dotty-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.
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 28 |
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 => |