aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Denotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-03 18:51:50 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:01:59 +0200
commit968d16c289aedc7532dae9225502789b507e22e3 (patch)
treee2b4c1dccf994cdaa11d8ef512851c48d361c39e /src/dotty/tools/dotc/core/Denotations.scala
parentf0249f2bdd8aeb349309dc1ea6ed248987c800f9 (diff)
downloaddotty-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/tools/dotc/core/Denotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala32
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) = {