aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Denotations.scala
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/dotc/core/Denotations.scala
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/dotc/core/Denotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala29
1 files changed, 24 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