aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala35
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala5
-rw-r--r--src/dotty/tools/dotc/core/Types.scala5
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) {