Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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 816cecf, 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 c9861cd (genesis of isCoDefinedWith). Before that we
get back to 3761cb4 (the dawn of Subversion.)
  • Loading branch information...
commit fdcc262070470e0968afcdf0036cc18781c52e33 1 parent 7c1d114
@retronym retronym authored
View
4 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
}
]
}
View
9 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)
View
57 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
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.