diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 35 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 5 |
3 files changed, 35 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 6502c4a40..756e0b02d 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -2,7 +2,7 @@ package dotty.tools package dotc package core -import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation } +import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation, NotDefinedHereDenotation } import Contexts.{Context, ContextBase} import Names.{Name, PreName} import Names.TypeName @@ -128,7 +128,17 @@ object Denotations { */ def atSignature(sig: Signature, site: Type = NoPrefix)(implicit ctx: Context): SingleDenotation - /** The variant of this denotation that's current in the given context. */ + /** The variant of this denotation that's current in the given context, or + * `NotDefinedHereDenotation` if this denotation does not exist at current phase, but + * is defined elsewhere in this run. + */ + def currentIfExists(implicit ctx: Context): Denotation + + /** The variant of this denotation that's current in the given context. + * If no such denotation exists: If Mode.FutureDefs is set, the + * denotation with each alternative at its first point of definition, + * otherwise a `NotDefinedHere` exception is thrown. + */ def current(implicit ctx: Context): Denotation /** Is this denotation different from NoDenotation or an ErrorDenotation? */ @@ -349,6 +359,8 @@ object Denotations { final def signature(implicit ctx: Context) = Signature.OverloadedSignature def atSignature(sig: Signature, site: Type)(implicit ctx: Context): SingleDenotation = denot1.atSignature(sig, site) orElse denot2.atSignature(sig, site) + def currentIfExists(implicit ctx: Context): Denotation = + derivedMultiDenotation(denot1.currentIfExists, denot2.currentIfExists) def current(implicit ctx: Context): Denotation = derivedMultiDenotation(denot1.current, denot2.current) def altsWith(p: Symbol => Boolean): List[SingleDenotation] = @@ -530,7 +542,7 @@ object Denotations { * is brought forward to be valid in the new runId. Otherwise * the symbol is stale, which constitutes an internal error. */ - def current(implicit ctx: Context): SingleDenotation = { + def currentIfExists(implicit ctx: Context): SingleDenotation = { val currentPeriod = ctx.period val valid = myValidFor if (valid.code <= 0) { @@ -593,17 +605,24 @@ object Denotations { //println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}") cur = cur.nextInRun cnt += 1 - if (cnt > MaxPossiblePhaseId) - if (ctx.mode is Mode.FutureDefsOK) - return current(ctx.withPhase(coveredInterval.firstPhaseId)) - else - throw new NotDefinedHere(demandOutsideDefinedMsg) + if (cnt > MaxPossiblePhaseId) return NotDefinedHereDenotation } cur } } } + def current(implicit ctx: Context): SingleDenotation = { + val d = currentIfExists + if (d ne NotDefinedHereDenotation) d else currentNoDefinedHere + } + + private def currentNoDefinedHere(implicit ctx: Context): SingleDenotation = + if (ctx.mode is Mode.FutureDefsOK) + current(ctx.withPhase(coveredInterval.firstPhaseId)) + else + throw new NotDefinedHere(demandOutsideDefinedMsg) + 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}" diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 275fb8257..b93585324 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1650,7 +1650,7 @@ object SymDenotations { } } - object NoDenotation extends SymDenotation( + class NoDenotation extends SymDenotation( NoSymbol, NoSymbol, "<none>".toTermName, Permanent, NoType) { override def exists = false override def isTerm = false @@ -1660,6 +1660,9 @@ object SymDenotations { validFor = Period.allInRun(NoRunId) // will be brought forward automatically } + val NoDenotation = new NoDenotation + val NotDefinedHereDenotation = new NoDenotation + // ---- Completion -------------------------------------------------------- /** Instances of LazyType are carried by uncompleted symbols. diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 512ddc41a..24f59ee43 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1244,7 +1244,10 @@ object Types { } case d => if (d.validFor.runId != ctx.period.runId) loadDenot - else d.current + else { + val newd = d.currentIfExists + if (newd ne NotDefinedHereDenotation) newd else loadDenot + } } if (ctx.typerState.ephemeral) record("ephemeral cache miss: loadDenot") else if (d.exists) { |