diff options
author | Martin Odersky <odersky@gmail.com> | 2014-07-03 18:51:50 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-07-17 11:01:59 +0200 |
commit | 968d16c289aedc7532dae9225502789b507e22e3 (patch) | |
tree | e2b4c1dccf994cdaa11d8ef512851c48d361c39e /src/dotty | |
parent | f0249f2bdd8aeb349309dc1ea6ed248987c800f9 (diff) | |
download | dotty-968d16c289aedc7532dae9225502789b507e22e3.tar.gz dotty-968d16c289aedc7532dae9225502789b507e22e3.tar.bz2 dotty-968d16c289aedc7532dae9225502789b507e22e3.zip |
Fixed problem with installAfter
The problem is that when an installAfter completely replaces a previous denotation, a symbol or NamedType
might still hang on to that denotation in the cache. We need to enforce that we switch to the new denotation.
This is done by setting the replaced denotation's validFor field to Nowhere.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index bdc67aa08..82ee6560d 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -512,7 +512,13 @@ object Denotations { def current(implicit ctx: Context): SingleDenotation = { val currentPeriod = ctx.period val valid = myValidFor - assert(valid.code > 0) + if (valid.code <= 0) { + // can happen if we sit on a stale denotation which has been replaced + // wholesale by an installAfter; in this case, proceed to the next + // denotation and try again. + if (validFor == Nowhere && nextInRun.validFor != Nowhere) return nextInRun.current + assert(false) + } if (valid.runId != currentPeriod.runId) bringForward.current else { @@ -551,6 +557,7 @@ object Denotations { cur = next } cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId) + //printPeriods(cur) //println(s"new denot: $cur, valid for ${cur.validFor}") } cur.current // multiple transformations could be required @@ -563,7 +570,11 @@ object Denotations { //println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}") cur = cur.nextInRun cnt += 1 - assert(cnt <= MaxPossiblePhaseId, s"seems to be a loop in Denotations for $this, currentPeriod = $currentPeriod") + if (cnt > MaxPossiblePhaseId) { + println(s"seems to be a loop in Denotations for $this, currentPeriod = $currentPeriod") + printPeriods(this) + assert(false) + } } cur } @@ -571,6 +582,19 @@ object Denotations { } } + private def printPeriods(current: SingleDenotation): Unit = { + print(s"periods for $this:") + var cur = current + var cnt = 0 + do { + print(" " + cur.validFor) + cur = cur.nextInRun + cnt += 1 + if (cnt > MaxPossiblePhaseId) { println(" ..."); return } + } while (cur ne current) + println() + } + /** Install this denotation to be the result of the given denotation transformer. * This is the implementation of the same-named method in SymDenotations. * It's placed here because it needs access to private fields of SingleDenotation. @@ -581,6 +605,8 @@ object Denotations { assert(ctx.phaseId == targetId, s"denotation update for $this called in phase ${ctx.phase}, expected was ${phase.next}") val current = symbol.current + // println(s"installing $this after $phase/${phase.id}, valid = ${current.validFor}") + // printPeriods(current) this.nextInRun = current.nextInRun this.validFor = Period(ctx.runId, targetId, current.validFor.lastPhaseId) if (current.validFor.firstPhaseId == targetId) { @@ -588,12 +614,14 @@ object Denotations { var prev = current while (prev.nextInRun ne current) prev = prev.nextInRun prev.nextInRun = this + current.validFor = Nowhere } else { // insert this denotation after current current.validFor = Period(ctx.runId, current.validFor.firstPhaseId, targetId - 1) current.nextInRun = this } + // printPeriods(this) } def staleSymbolError(implicit ctx: Context) = { |