summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-01-17 09:27:55 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-01-20 23:16:59 +0100
commit357905c9555f8081784acd1912cf0681b145ca8b (patch)
treeb467214d8084efc48a736f34523405502c2cee06
parent731ed385dea0196305a0c527303649ea0325de63 (diff)
downloadscala-357905c9555f8081784acd1912cf0681b145ca8b.tar.gz
scala-357905c9555f8081784acd1912cf0681b145ca8b.tar.bz2
scala-357905c9555f8081784acd1912cf0681b145ca8b.zip
SI-5954 Invalidate TypeRef cache when opening package object
I noticed that the pos/5954d was tripping a println "assertion". This stemmed from an inconsistency between `TypeRef#{parents, baseTypeSeq}` for a package objects compiled from source that also has a class file from a previous compilation run. I've elevated the println to a devWarning, and changed `updatePosFlags`, the home of this evil symbol overwriting, to invalidate the caches in the symbols info. Yuck. I believe that this symptom is peculiar to package objects because of the way that the completer for packages calls `parents` during the Namer phase for package objects, before we switch the symbol to represent the package-object-from-source. But it seems prudent to defensively invalidate the caches for any symbol that finds its way into `updatePosFlags`.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
-rw-r--r--test/files/pos/t5954d.flags1
-rw-r--r--test/files/pos/t5954d/A_1.scala6
-rw-r--r--test/files/pos/t5954d/B_2.scala7
6 files changed, 26 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 48c2c55d7c..fd093614b5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -148,6 +148,13 @@ trait Namers extends MethodSynthesis {
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
debuglog("[overwrite] " + sym)
val newFlags = (sym.flags & LOCKED) | flags
+ sym.rawInfo match {
+ case tr: TypeRef =>
+ // !!! needed for: pos/t5954d; the uniques type cache will happilly serve up the same TypeRef
+ // over this mutated symbol, and we witness a stale cache for `parents`.
+ tr.invalidateCaches()
+ case _ =>
+ }
sym reset NoType setFlag newFlags setPos pos
sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 95f2620061..f5893172e8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -857,7 +857,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val baseClass = clazz.info.baseTypeSeq(i).typeSymbol
seenTypes(i) match {
case Nil =>
- println("??? base "+baseClass+" not found in basetypes of "+clazz)
+ devWarning(s"base $baseClass not found in basetypes of $clazz. This might indicate incorrect caching of TypeRef#parents.")
case _ :: Nil =>
;// OK
case tp1 :: tp2 :: _ =>
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 99e6ae633f..437b962abf 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2218,6 +2218,10 @@ trait Types
trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args))
toBoolean(trivial)
}
+ private[scala] def invalidateCaches(): Unit = {
+ parentsPeriod = NoPeriod
+ baseTypeSeqPeriod = NoPeriod
+ }
private[reflect] var parentsCache: List[Type] = _
private[reflect] var parentsPeriod = NoPeriod
private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
diff --git a/test/files/pos/t5954d.flags b/test/files/pos/t5954d.flags
new file mode 100644
index 0000000000..6ced0e7090
--- /dev/null
+++ b/test/files/pos/t5954d.flags
@@ -0,0 +1 @@
+-Xfatal-warnings -Xdev
diff --git a/test/files/pos/t5954d/A_1.scala b/test/files/pos/t5954d/A_1.scala
new file mode 100644
index 0000000000..8465e8f8c6
--- /dev/null
+++ b/test/files/pos/t5954d/A_1.scala
@@ -0,0 +1,6 @@
+package p {
+ package object base {
+ class B
+ object B
+ }
+}
diff --git a/test/files/pos/t5954d/B_2.scala b/test/files/pos/t5954d/B_2.scala
new file mode 100644
index 0000000000..a4aa2eb587
--- /dev/null
+++ b/test/files/pos/t5954d/B_2.scala
@@ -0,0 +1,7 @@
+package p {
+ trait T {
+ class B
+ object B
+ }
+ package object base extends T
+}