diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-26 14:53:42 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-26 14:53:42 +0200 |
commit | 08c6eacaf59386ed26aeead472e1df2c5944a3fb (patch) | |
tree | dff3e1c4ae4d1f1b62e4e3509231f9a5f16024ed | |
parent | 97d89afc4769c4badb42284c9b5d97b663f870f6 (diff) | |
download | dotty-08c6eacaf59386ed26aeead472e1df2c5944a3fb.tar.gz dotty-08c6eacaf59386ed26aeead472e1df2c5944a3fb.tar.bz2 dotty-08c6eacaf59386ed26aeead472e1df2c5944a3fb.zip |
thisType of a module class is a term ref to the source module.
Module classes now always get the sourceModule term ref as their this type.
We would like to eliminate ThisType() of a module class completely, as this
hangs on to a symbol which might become stale for globally accessible modules.
This commit is the first step. It contains the change to thisType and the necessary
fixes to make the test suite pass.
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 2 |
4 files changed, 27 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 8d243a0cb..554517cd7 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -469,6 +469,15 @@ object Trees { case class This[-T >: Untyped] private[ast] (qual: TypeName) extends DenotingTree[T] with TermTree[T] { type ThisTree[-T >: Untyped] = This[T] + // Denotation of a This tree is always the udnerlying class; needs correction for modules. + override def denot(implicit ctx: Context): Denotation = { + tpe match { + case tpe @ TermRef(pre, _) if tpe.symbol is Module => + tpe.symbol.moduleClass.denot.asSeenFrom(pre) + case _ => + super.denot + } + } } /** C.super[mix], where qual = C.this */ diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 63ce7f756..a3828552d 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -467,14 +467,17 @@ object SymDenotations { (linked ne NoSymbol) && accessWithin(linked) } - /** Is `pre` of the form C.this, where C is exactly the owner of this symbol, + /** Is `pre` the same as C.thisThis, where C is exactly the owner of this symbol, * or, if this symbol is protected, a subclass of the owner? */ def isCorrectThisType(pre: Type): Boolean = pre match { case ThisType(pclazz) => (pclazz eq owner) || (this is Protected) && pclazz.derivesFrom(owner) - case _ => false + case pre: TermRef => + pre.symbol.moduleClass == owner + case _ => + false } /** Is protected access to target symbol permitted? */ @@ -1002,11 +1005,13 @@ object SymDenotations { myThisType } - private def computeThisType(implicit ctx: Context): Type = ThisType(classSymbol) /* - if ((this is PackageClass) && !isRoot) - TermRef(owner.thisType, name.toTermName) - else - ThisType(classSymbol) */ + private def computeThisType(implicit ctx: Context): Type = + if (this.is(Module, butNot = Package)) { + val pre = owner.thisType + if ((pre eq NoPrefix) || ctx.erasedTypes) pre select sourceModule + else TermRef.withSig(pre, name.sourceModuleName, Signature.NotAMethod) + } + else ThisType(classSymbol) private[this] var myTypeRef: TypeRef = null diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index e59c28ca2..a6ba7d9a0 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1353,13 +1353,13 @@ object Types { } override def newLikeThis(prefix: Type)(implicit ctx: Context): TermRef = { - if (sig != Signature.NotAMethod && - sig != Signature.OverloadedSignature && - symbol.exists) { + val candidate = TermRef.withSig(prefix, name, sig) + if (symbol.exists && !candidate.symbol.exists) { // recompute from previous symbol val ownSym = symbol - TermRef.all(prefix, name).withDenot(asMemberOf(prefix).disambiguate(_ eq ownSym)) + val newd = asMemberOf(prefix) + candidate.withDenot(asMemberOf(prefix).suchThat(_ eq ownSym)) } - else TermRef.withSig(prefix, name, sig) + else candidate } override def equals(that: Any) = that match { diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 2317079e1..c9f838c0b 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -49,7 +49,7 @@ trait TypeAssigner { case TypeAlias(ref) => apply(ref) case info: ClassInfo => - mapOver(info.instantiatedParents.reduceLeft(AndType(_, _))) + mapOver(info.instantiatedParents.reduceLeft(ctx.typeComparer.andType(_, _))) case _ => mapOver(tp) } |