diff options
author | Martin Odersky <odersky@gmail.com> | 2016-02-15 11:01:11 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-02-17 18:39:36 +0100 |
commit | 6324a75d39e4eab8a405dafd19480a0dbd4841ad (patch) | |
tree | d030479ba9211bcccc3ff6d6492bdfea7a89b96c /src/dotty/tools/dotc/core/SymDenotations.scala | |
parent | f3ba2dc0c69b31e3fa839f3c13c664ed6c143371 (diff) | |
download | dotty-6324a75d39e4eab8a405dafd19480a0dbd4841ad.tar.gz dotty-6324a75d39e4eab8a405dafd19480a0dbd4841ad.tar.bz2 dotty-6324a75d39e4eab8a405dafd19480a0dbd4841ad.zip |
Add diagnostic why a symbol is stale.
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 30 |
1 files changed, 30 insertions, 0 deletions
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 { |