aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala5
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala30
2 files changed, 34 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 2af3f463d..0f32d7ff3 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -590,7 +590,10 @@ object Denotations {
} while (d ne denot)
this
case _ =>
- if (coveredInterval.containsPhaseId(ctx.phaseId)) staleSymbolError
+ if (coveredInterval.containsPhaseId(ctx.phaseId)) {
+ if (ctx.settings.debug.value) ctx.traceInvalid(this)
+ staleSymbolError
+ }
else NoDenotation
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 4495b4096..05c3fdd52 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -57,7 +57,37 @@ trait SymDenotations { this: Context =>
} catch {
case ex: StaleSymbol => false
}
+
+ /** Explain why symbol is invalid; used for debugging only */
+ def traceInvalid(denot: Denotation): Boolean = {
+ def show(d: Denotation) = s"$d#${d.symbol.id}"
+ def explain(msg: String) = {
+ println(s"${show(denot)} is invalid at ${this.period} because $msg")
+ false
+ }
+ denot match {
+ case denot: SymDenotation =>
+ def explainSym(msg: String) = explain(s"$msg\n defined = ${denot.definedPeriodsString}")
+ if (denot.is(ValidForever) || denot.isRefinementClass) true
+ else {
+ implicit val ctx: Context = this
+ val initial = denot.initial
+ if ((initial ne denot) || ctx.phaseId != initial.validFor.firstPhaseId) {
+ ctx.withPhase(initial.validFor.firstPhaseId).traceInvalid(initial.asSymDenotation)
+ } else try {
+ val owner = denot.owner.denot
+ if (!traceInvalid(owner)) explainSym("owner is invalid")
+ else if (!owner.isClass || owner.isRefinementClass || denot.isSelfSym) true
+ else if (owner.unforcedDecls.lookupAll(denot.name) contains denot.symbol) true
+ else explainSym(s"decls of ${show(owner)} are ${owner.unforcedDecls.lookupAll(denot.name).toList}, do not contain ${denot.symbol}")
+ } catch {
+ case ex: StaleSymbol => explainSym(s"$ex was thrown")
+ }
+ }
+ case _ =>
+ explain("denotation is not a SymDenotation")
}
+ }
}
object SymDenotations {