diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-18 12:56:17 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-18 12:56:29 +0100 |
commit | a0d6eedeb64d45af53a3cb93ab48b22855e3a61c (patch) | |
tree | d511e09557cc91b90c7da76b124647a5c0bdca30 /src/dotty | |
parent | cb3adb9ff93c45101150dd71b927295e327b3c81 (diff) | |
download | dotty-a0d6eedeb64d45af53a3cb93ab48b22855e3a61c.tar.gz dotty-a0d6eedeb64d45af53a3cb93ab48b22855e3a61c.tar.bz2 dotty-a0d6eedeb64d45af53a3cb93ab48b22855e3a61c.zip |
Fixing problems around isAbsent
A Symbol is absent if (1) it equals NoSymbol, or (2) it's type is NoType or (3) it is a module with an module class which is absent.
Note that isAbsent does not force symbols. The info has to be completed explicitly to check.
Criterion (3) is missing, we now take it into account.
Also, made ClassDenotation ops more robost in tge face of possibilty of being absent.
Finally, refined logic in Typer, to complete a symbol before checking absent.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 1 |
2 files changed, 14 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 4cf392f13..e94643f8a 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -263,8 +263,9 @@ object SymDenotations { myInfo = NoType /** Is symbol known to not exist? */ - final def isAbsent: Boolean = - myInfo == NoType + final def isAbsent(implicit ctx: Context): Boolean = + myInfo == NoType || + (this is (ModuleVal, butNot = Package)) && moduleClass.isAbsent /** Is this symbol the root class or its companion object? */ final def isRoot: Boolean = @@ -729,7 +730,7 @@ object SymDenotations { def classSymbol: ClassSymbol = symbol.asInstanceOf[ClassSymbol] /** The info asserted to have type ClassInfo */ - def classInfo(implicit ctx: Context): ClassInfo = super.info.asInstanceOf[ClassInfo] + def classInfo(implicit ctx: Context): ClassInfo = info.asInstanceOf[ClassInfo] /** TODO: Document why caches are supposedly safe to use */ private[this] var myTypeParams: List[TypeSymbol] = _ @@ -742,12 +743,17 @@ object SymDenotations { myTypeParams } + private def myClassParents: List[TypeRef] = info match { + case classInfo: ClassInfo => classInfo.myClassParents + case _ => Nil + } + /** The denotation is fully completed: all attributes are fully defined. * ClassDenotations compiled from source are first completed, then fully completed. * @see Namer#ClassCompleter */ private def isFullyCompleted(implicit ctx: Context): Boolean = - isCompleted && classInfo.myClassParents.nonEmpty + isCompleted && myClassParents.nonEmpty /** A key to verify that all caches influenced by parent classes are valid */ private var parentDenots: List[Denotation] = null @@ -757,8 +763,8 @@ object SymDenotations { * because the latter does not ensure that the `parentDenots` key * is up-to-date, which might lead to invalid caches later on. */ - def classParents(implicit ctx: Context) = { - val ps = classInfo.myClassParents + def classParents(implicit ctx: Context): List[TypeRef] = { + val ps = myClassParents if (parentDenots == null && ps.nonEmpty) parentDenots = ps map (_.denot) ps } @@ -766,7 +772,7 @@ object SymDenotations { /** Are caches influenced by parent classes still valid? */ private def parentsAreValid(implicit ctx: Context): Boolean = parentDenots == null || - parentDenots.corresponds(classInfo.myClassParents)(_ eq _.denot) + parentDenots.corresponds(myClassParents)(_ eq _.denot) /** If caches influenced by parent classes are still valid, the denotation * itself, otherwise a freshly initialized copy. diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index d16ec53ae..31964ce98 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -67,6 +67,7 @@ class Typer extends Namer with Applications with Implicits { def reallyExists(denot: Denotation)(implicit ctx: Context): Boolean = denot.exists && { val sym = denot.symbol + sym.ensureCompleted (sym eq NoSymbol) || !sym.isAbsent } |