diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 9efa9cfe9a79..9aaea44f3262 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -668,8 +668,10 @@ object Denotations { private[this] var myValidFor: Period = Nowhere def validFor = myValidFor - def validFor_=(p: Period) = + def validFor_=(p: Period) = { myValidFor = p + symbol.invalidateDenotCache() + } /** The next SingleDenotation in this run, with wrap-around from last to first. * diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 8c51c2d5e387..222c3dcd58ad 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1851,7 +1851,7 @@ object SymDenotations { override def owner: Symbol = throw new AssertionError("NoDenotation.owner") override def computeAsSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = this override def mapInfo(f: Type => Type)(implicit ctx: Context): SingleDenotation = this - validFor = Period.allInRun(NoRunId) // will be brought forward automatically + validFor = Period.allInRun(NoRunId) } @sharable val NoDenotation = new NoDenotation diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 78e3ceae1014..77da1f5f16f7 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -398,19 +398,34 @@ object Symbols { /** The last denotation of this symbol */ private[this] var lastDenot: SymDenotation = _ + private[this] var checkedPeriod: Period = Nowhere + + private[core] def invalidateDenotCache() = { checkedPeriod = Nowhere } /** Set the denotation of this symbol */ - private[core] def denot_=(d: SymDenotation) = + private[core] def denot_=(d: SymDenotation) = { lastDenot = d + checkedPeriod = Nowhere + } /** The current denotation of this symbol */ final def denot(implicit ctx: Context): SymDenotation = { - var denot = lastDenot - if (!(denot.validFor contains ctx.period)) { - denot = denot.current.asInstanceOf[SymDenotation] - lastDenot = denot - } - denot + val lastd = lastDenot + if (checkedPeriod == ctx.period) lastd + else computeDenot(lastd) + } + + private def computeDenot(lastd: SymDenotation)(implicit ctx: Context): SymDenotation = { + val now = ctx.period + checkedPeriod = now + if (lastd.validFor contains now) lastd else recomputeDenot(lastd) + } + + /** Overridden in NoSymbol */ + protected def recomputeDenot(lastd: SymDenotation)(implicit ctx: Context) = { + val newd = lastd.current.asInstanceOf[SymDenotation] + lastDenot = newd + newd } /** The initial denotation of this symbol, without going through `current` */ @@ -631,8 +646,8 @@ object Symbols { @sharable object NoSymbol extends Symbol(NoCoord, 0) { denot = NoDenotation - override def associatedFile(implicit ctx: Context): AbstractFile = NoSource.file + override def recomputeDenot(lastd: SymDenotation)(implicit ctx: Context): SymDenotation = NoDenotation } implicit class Copier[N <: Name](sym: Symbol { type ThisName = N })(implicit ctx: Context) {