summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@gmail.com>2012-10-28 18:57:30 +0100
committerHubert Plociniczak <hubert.plociniczak@gmail.com>2012-10-28 23:29:43 +0100
commit0527b2549bcada2fda2201daa630369b377d0877 (patch)
treebfe1dd6d87106ae27647c181d25ef3bfdfa8d8df
parent2c554249fd8e99286134b217027b6e3cb2c92d77 (diff)
downloadscala-0527b2549bcada2fda2201daa630369b377d0877.tar.gz
scala-0527b2549bcada2fda2201daa630369b377d0877.tar.bz2
scala-0527b2549bcada2fda2201daa630369b377d0877.zip
Fixes SI-5031 for separate compilation scenario.
When you have a conflicting member in package object and normal package that share the same namespace we remove the latter ClassSymbol from the scope. Now, this has an unpleasant consequence that companionClass/companionModule/companionSymbol no longer work correctly as they rely on finding the correspondent symbol using decls of the owner. This fixes the problem of SI-5031 for separate compilation. Why the above change matters for finding foo.bar.Foo? Because when parsing the class we needed information about the static module (and we have the correct module symbol when completing the info). It's just that 043ce6d0565c9d5d960 relied on no longer valid assumptions. So we were getting NoSymbol and sym.exist was failing. Obviously a more complete solution would be better if we didn't rely on the scope but that's too big to change for 2.10.0.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala5
-rw-r--r--test/files/pos/t5031_3/Foo_1.scala5
-rw-r--r--test/files/pos/t5031_3/Main_2.scala6
-rw-r--r--test/files/pos/t5031_3/package.scala6
5 files changed, 24 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index f9eeb41e6d..6d7948f0a9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -558,7 +558,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
def innerClassSymbolFor(s: Symbol): Symbol =
if (s.isClass) s else if (s.isModule) s.moduleClass else NoSymbol
- /** Return the a name of this symbol that can be used on the Java platform. It removes spaces from names.
+ /** Return the name of this symbol that can be used on the Java platform. It removes spaces from names.
*
* Special handling:
* scala.Nothing erases to scala.runtime.Nothing$
@@ -607,7 +607,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
case None =>
reverseJavaName.put(internalName, trackedSym)
case Some(oldsym) =>
- assert((oldsym == trackedSym) || (oldsym == RuntimeNothingClass) || (oldsym == RuntimeNullClass), // In contrast, neither NothingClass nor NullClass show up bytecode-level.
+ assert((oldsym == trackedSym) || (oldsym == RuntimeNothingClass) || (oldsym == RuntimeNullClass) ||
+ (oldsym.isModuleClass && (oldsym.sourceModule == trackedSym.sourceModule)), // In contrast, neither NothingClass nor NullClass show up bytecode-level.
"how can getCommonSuperclass() do its job if different class symbols get the same bytecode-level internal name: " + internalName)
}
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 8fd8dfaf83..9caafe6912 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -94,7 +94,10 @@ abstract class ClassfileParser {
pushBusy(root) {
this.in = new AbstractFileReader(file)
this.clazz = if (root.isModule) root.companionClass else root
- this.staticModule = clazz.companionModule
+ // WARNING! do no use clazz.companionModule to find staticModule.
+ // In a situation where root can be defined, but its companionClass not,
+ // this would give incorrect results (see SI-5031 in separate compilation scenario)
+ this.staticModule = if (root.isModule) root else root.companionModule
this.isScala = false
parseHeader
diff --git a/test/files/pos/t5031_3/Foo_1.scala b/test/files/pos/t5031_3/Foo_1.scala
new file mode 100644
index 0000000000..5934a6ba79
--- /dev/null
+++ b/test/files/pos/t5031_3/Foo_1.scala
@@ -0,0 +1,5 @@
+package foo.bar
+
+object Foo {
+ def bar = 42
+}
diff --git a/test/files/pos/t5031_3/Main_2.scala b/test/files/pos/t5031_3/Main_2.scala
new file mode 100644
index 0000000000..2079460b83
--- /dev/null
+++ b/test/files/pos/t5031_3/Main_2.scala
@@ -0,0 +1,6 @@
+package org.example
+
+object Main extends App {
+ println(foo.bar.Foo.bar)
+}
+
diff --git a/test/files/pos/t5031_3/package.scala b/test/files/pos/t5031_3/package.scala
new file mode 100644
index 0000000000..23fede7d04
--- /dev/null
+++ b/test/files/pos/t5031_3/package.scala
@@ -0,0 +1,6 @@
+package foo
+
+package object bar {
+ type Foo = Int => String
+}
+