diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 30 |
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 { |