aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-10 14:48:42 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:02:01 +0200
commit34202eb4e13921190bf4992ab33d9d69975f4940 (patch)
treef601215270c4fb45e398f5ac4465142779eee007 /src/dotty/tools
parentcd82c859bb2fe05de257cbc81e97bedd2bbf2a4a (diff)
downloaddotty-34202eb4e13921190bf4992ab33d9d69975f4940.tar.gz
dotty-34202eb4e13921190bf4992ab33d9d69975f4940.tar.bz2
dotty-34202eb4e13921190bf4992ab33d9d69975f4940.zip
Avoid some classes of StaleSymbol errors
If a symbol is defined in phases M..N, and that symbol is then accessed in a phase before M, but in a new run, we should not issue a stale symbol error (after all, the symbol is not defined yet). Instead we now return a NoDenotation.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala29
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala7
2 files changed, 31 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index a2c8af886..43fff62ec 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -494,7 +494,8 @@ object Denotations {
} while (d ne denot)
initial.syncWithParents
case _ =>
- staleSymbolError
+ if (coveredInterval.containsPhaseId(ctx.phaseId)) staleSymbolError
+ else NoDenotation
}
/** Produce a denotation that is valid for the given context.
@@ -570,14 +571,16 @@ object Denotations {
//println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}")
cur = cur.nextInRun
cnt += 1
- assert(cnt <= MaxPossiblePhaseId,
- s"demanding denotation of $this outside defined interval: defined periods are${definedPeriodsString}")
+ assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
}
cur
}
}
}
+ private def demandOutsideDefinedMsg(implicit ctx: Context): String =
+ s"demanding denotation of $this at phase ${ctx.phase}(${ctx.phaseId}) outside defined interval: defined periods are${definedPeriodsString}"
+
/** 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.
@@ -616,6 +619,22 @@ object Denotations {
throw new StaleSymbol(msg)
}
+ /** The period (interval of phases) for which there exists
+ * a valid denotation in this flock.
+ */
+ def coveredInterval(implicit ctx: Context): Period = {
+ var cur = this
+ var cnt = 0
+ var interval = validFor
+ do {
+ cur = cur.nextInRun
+ cnt += 1
+ assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
+ interval |= cur.validFor
+ } while (cur ne this)
+ interval
+ }
+
/** For ClassDenotations only:
* If caches influenced by parent classes are still valid, the denotation
* itself, otherwise a freshly initialized copy.
@@ -643,7 +662,7 @@ object Denotations {
// ------ PreDenotation ops ----------------------------------------------
final def first = this
- final def toDenot(pre: Type)(implicit ctx: Context) = this
+ final def toDenot(pre: Type)(implicit ctx: Context): Denotation = this
final def containsSym(sym: Symbol): Boolean = hasUniqueSym && (symbol eq sym)
final def containsSig(sig: Signature)(implicit ctx: Context) =
exists && (signature matches sig)
@@ -790,7 +809,7 @@ object Denotations {
else DenotUnion(this, that)
}
- case class DenotUnion(denots1: PreDenotation, denots2: PreDenotation) extends PreDenotation {
+ final case class DenotUnion(denots1: PreDenotation, denots2: PreDenotation) extends PreDenotation {
assert(denots1.exists && denots2.exists, s"Union of non-existing denotations ($denots1) and ($denots2)")
def exists = true
def first = denots1.first
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index 4ab04fad0..e0d9e3b5d 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -67,6 +67,8 @@ object Periods {
/** The first phase of this period */
def firstPhaseId = lastPhaseId - (code & PhaseMask)
+ def containsPhaseId(id: PhaseId) = firstPhaseId <= id && id <= lastPhaseId
+
/** Does this period contain given period? */
def contains(that: Period): Boolean = {
// Let this = (r1, l1, d1), that = (r2, l2, d2)
@@ -106,6 +108,11 @@ object Periods {
else
Nowhere
+ def | (that: Period): Period =
+ Period(this.runId,
+ this.firstPhaseId min that.firstPhaseId,
+ this.lastPhaseId max that.lastPhaseId)
+
override def toString = s"Period($firstPhaseId..$lastPhaseId, run = $runId)"
}