aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-31 17:59:27 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-31 18:04:37 +0200
commit2bfff5e5457223114e24e112aa6715f6a9d0c3f3 (patch)
tree4a4e4f7a4a0f220c83236eceea8f71c9f83e9e24
parente7e1cdce8eb25452ed97e8a019cc63aaecab6fc6 (diff)
downloaddotty-2bfff5e5457223114e24e112aa6715f6a9d0c3f3.tar.gz
dotty-2bfff5e5457223114e24e112aa6715f6a9d0c3f3.tar.bz2
dotty-2bfff5e5457223114e24e112aa6715f6a9d0c3f3.zip
Fix to elidable prefix.
The previous condition was too weak. The fix revealed a problem where an "undefined symbol" error was thrown when reading an alias annotation in the unpickler. The exception is now suppressed, the comment explains why.
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala31
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala7
2 files changed, 26 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index a9b1f1197..8f9a0d4b2 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -252,17 +252,26 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
// ------ Making references ------------------------------------------------------
- def prefixIsElidable(tp: NamedType)(implicit ctx: Context) = tp.prefix match {
- case NoPrefix =>
- true
- case pre: ThisType =>
- pre.cls.isStaticOwner ||
- tp.symbol.is(ParamOrAccessor) && tp.symbol.maybeOwner.enclosingClass == pre.cls
- case pre: TermRef =>
- pre.symbol.is(Module) && pre.symbol.isStatic
- case _ =>
- false
- }
+ def prefixIsElidable(tp: NamedType)(implicit ctx: Context) =
+ try
+ tp.prefix match {
+ case NoPrefix =>
+ true
+ case pre: ThisType =>
+ pre.cls.isStaticOwner ||
+ tp.symbol.is(ParamOrAccessor) && ctx.owner.enclosingClass.derivesFrom(pre.cls)
+ case pre: TermRef =>
+ pre.symbol.is(Module) && pre.symbol.isStatic
+ case _ =>
+ false
+ }
+ catch {
+ case ex: NotDefinedHere => false
+ // NotDefinedHere can happen if we create a reference during unpickling
+ // (which will be at phase frontend), but the request comes at a later
+ // phase from within a context with owners that are not yet defined at
+ // phase frontend. An example case arises when compiling pos/i143.scala
+ }
def needsSelect(tp: Type)(implicit ctx: Context) = tp match {
case tp: TermRef => !prefixIsElidable(tp)
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 376e63c41..c56d2b882 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -576,7 +576,7 @@ object Denotations {
//println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}")
cur = cur.nextInRun
cnt += 1
- assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
+ if (cnt > MaxPossiblePhaseId) throw new NotDefinedHere(demandOutsideDefinedMsg)
}
cur
}
@@ -890,5 +890,10 @@ object Denotations {
util.Stats.record("stale symbol")
override def getMessage() = msg
}
+
+ class NotDefinedHere(msg: => String) extends Exception {
+ util.Stats.record("not defined here")
+ override def getMessage() = msg
+ }
}