summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-12-04 17:45:10 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-12-06 14:30:56 +0100
commitfdcc262070470e0968afcdf0036cc18781c52e33 (patch)
tree26c07bf7bc97dc2a3f37c9180cca50d455362508
parent7c1d1149291e1b83c96a0f6954144b9e97c030ea (diff)
downloadscala-fdcc262070470e0968afcdf0036cc18781c52e33.tar.gz
scala-fdcc262070470e0968afcdf0036cc18781c52e33.tar.bz2
scala-fdcc262070470e0968afcdf0036cc18781c52e33.zip
SI-8029 Avoid multi-run cyclic error with companions, package object
The bug report suggests this problem only became visible in the IDE *after* 2.10.3, but I tested an IDE with exactly 2.10.3 and saw the same problem. In fact, my test case fails as far back as 2.10.0. I suspect the problem showed up after 816cecf9a9, which checks that pairs of companion symbols are codefined eagerly in Namers. This commit modifies the check of `rawInfo ne NoType` in `isCoDefinedWith` to avoid triggering adaptation of types from the previous run. I'm not sure of the precise intent of that check. I looked at c9861cd198 (genesis of isCoDefinedWith). Before that we get back to 3761cb4b3a1 (the dawn of Subversion.)
-rw-r--r--bincompat-forward.whitelist.conf4
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala9
-rw-r--r--test/files/run/t8029.scala57
3 files changed, 69 insertions, 1 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 2ece671638..3b61a02bce 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -1431,6 +1431,10 @@ filter {
{
matchName="scala.reflect.internal.Trees#Modifiers.isDeferredNotDefault"
problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.Symbols#Symbol.rawInfoIsNoType"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 45c16b7302..a9299cc1bc 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -1282,6 +1282,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def hasRawInfo: Boolean = infos ne null
def hasCompleteInfo = hasRawInfo && rawInfo.isComplete
+ // does not run adaptToNewRun, which is prone to trigger cycles (SI-8029)
+ // TODO: give this a better name if you understand the intent of the caller.
+ // Is it something to do with `reallyExists` or `isStale`?
+ final def rawInfoIsNoType: Boolean = {
+ hasRawInfo && (infos.info eq NoType)
+ }
+
/** Return info without checking for initialization or completing */
def rawInfo: Type = {
var infos = this.infos
@@ -1928,7 +1935,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = (
- (this.rawInfo ne NoType)
+ !rawInfoIsNoType
&& (this.effectiveOwner == that.effectiveOwner)
&& ( !this.effectiveOwner.isPackageClass
|| (this.sourceFile eq null)
diff --git a/test/files/run/t8029.scala b/test/files/run/t8029.scala
new file mode 100644
index 0000000000..dbd5c41387
--- /dev/null
+++ b/test/files/run/t8029.scala
@@ -0,0 +1,57 @@
+import scala.tools.partest._
+import scala.tools.nsc._
+
+object Test extends DirectTest {
+
+ override def extraSettings: String = "-usejavacp -nowarn -Ystop-after:typer"
+
+ override def code = "" // not used
+
+ def code1 = """
+package object p1 {
+ trait A
+ object A
+}
+ """
+
+ def code2 = """
+package object p2 {
+ class A
+ object A
+}
+ """
+
+ def code3 = """
+package object p3 {
+ object A
+ trait A
+}
+ """
+
+ def code4 = """
+package object p4 {
+ object A
+ trait A
+}
+ """
+
+ def show() {
+ val global = newCompiler()
+ import global._
+ def typecheck(code: String): Unit = {
+ val r = new Run
+ val sourceFile = newSources(code).head
+ global.reporter.reset()
+ r.compileSources(sourceFile :: Nil)
+ assert(!global.reporter.hasErrors)
+ }
+
+ def typecheckTwice(code: String): Unit = {
+ typecheck(code)
+ typecheck(code)
+ }
+
+ // was: illegal cyclic reference involving package ...
+ Seq(code1, code2, code3, code4) foreach typecheckTwice
+ }
+}