diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 7 | ||||
-rw-r--r-- | test/files/pos/t7264/A_1.scala | 11 | ||||
-rw-r--r-- | test/files/pos/t7264/B_2.scala | 7 |
4 files changed, 28 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 981dfb24fe..eafe03d5cd 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1395,9 +1395,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter) def registerPickle(sym: Symbol): Unit = () /** does this run compile given class, module, or case factory? */ + // NOTE: Early initialized members temporarily typechecked before the enclosing class, see typedPrimaryConstrBody! + // Here we work around that wrinkle by claiming that a top-level, early-initialized member is compiled in + // *every* run. This approximation works because this method is exclusively called with `this` == `currentRun`. def compiles(sym: Symbol): Boolean = if (sym == NoSymbol) false else if (symSource.isDefinedAt(sym)) true + else if (sym.isTopLevel && sym.isEarlyInitialized) true else if (!sym.isTopLevel) compiles(sym.enclosingTopLevelClass) else if (sym.isModuleClass) compiles(sym.sourceModule) else false diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 4683fca192..0305aab844 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1686,8 +1686,13 @@ trait Namers extends MethodSynthesis { * call this method? */ def companionSymbolOf(original: Symbol, ctx: Context): Symbol = { + val owner = original.owner + // SI-7264 Force the info of owners from previous compilation runs. + // Doing this generally would trigger cycles; that's what we also + // use the lower-level scan through the current Context as a fall back. + if (!currentRun.compiles(owner)) owner.initialize original.companionSymbol orElse { - ctx.lookup(original.name.companionName, original.owner).suchThat(sym => + ctx.lookup(original.name.companionName, owner).suchThat(sym => (original.isTerm || sym.hasModuleFlag) && (sym isCoDefinedWith original) ) diff --git a/test/files/pos/t7264/A_1.scala b/test/files/pos/t7264/A_1.scala new file mode 100644 index 0000000000..044d0110a2 --- /dev/null +++ b/test/files/pos/t7264/A_1.scala @@ -0,0 +1,11 @@ +object Foo { + object Values { + implicit def fromInt(x: Int): Values = ??? + } + trait Values +} +final class Foo(name: String) { + def bar(values: Foo.Values): Bar = ??? +} + +trait Bar diff --git a/test/files/pos/t7264/B_2.scala b/test/files/pos/t7264/B_2.scala new file mode 100644 index 0000000000..869c51481d --- /dev/null +++ b/test/files/pos/t7264/B_2.scala @@ -0,0 +1,7 @@ +object Test { + // if the following line is uncommented, things compile + // type X = Foo.Values + + + def foo(f: Foo) = f.bar(0 /* : Foo.Values */) +} |