summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-07-28 07:04:26 +0000
committerPaul Phillips <paulp@improving.org>2011-07-28 07:04:26 +0000
commit892ecd2db75cb41cbcb582c26c2a7b32186625c0 (patch)
treeef7a68a88f4e2cbb4506afdf7f076f6119a2365c
parent5dbb616610b616bff7ec8bb9b78a6f8a59203d7d (diff)
downloadscala-892ecd2db75cb41cbcb582c26c2a7b32186625c0.tar.gz
scala-892ecd2db75cb41cbcb582c26c2a7b32186625c0.tar.bz2
scala-892ecd2db75cb41cbcb582c26c2a7b32186625c0.zip
Changed forwarders not to generate final method...
Changed forwarders not to generate final methods, which otherwise would induce VerifyErrors anytime the companion class was subclassed and had a method with the same signature. Closes SI-4827, no review.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala19
-rw-r--r--test/files/run/bug4827.scala15
-rw-r--r--test/files/run/bug4827b.scala18
3 files changed, 40 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index ac76f97b77..03de24c550 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -951,14 +951,18 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
/** Add a forwarder for method m */
- def addForwarder(jclass: JClass, module: Symbol, m: Symbol, accessFlags: Int) {
+ def addForwarder(jclass: JClass, module: Symbol, m: Symbol) {
val moduleName = javaName(module)
val methodInfo = module.thisType.memberInfo(m)
val paramJavaTypes = methodInfo.paramTypes map javaType
val paramNames = 0 until paramJavaTypes.length map ("x_" + _)
+ /** Forwarders must not be marked final, as the JVM will not allow
+ * redefinition of a final static method, and we don't know what classes
+ * might be subclassing the companion class. See SI-4827.
+ */
val mirrorMethod = jclass.addNewMethod(
- accessFlags,
+ PublicStatic,
javaName(m),
javaType(methodInfo.resultType),
mkArray(paramJavaTypes),
@@ -1004,15 +1008,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val linkedClass = moduleClass.companionClass
val linkedModule = linkedClass.companionSymbol
- /** If we use the usual algorithm for forwarders, we run into a problem if
- * an object extends its companion class. However, there is an out: since
- * all the forwarders are static, inheriting from the class is no problem
- * so long as the methods aren't final (the JVM will not allow redefinition
- * of a final static method.) Thus the following.
- */
- val isIncestuous = moduleClass.tpe <:< linkedClass.tpe
- val accessFlags = if (isIncestuous) PublicStatic else PublicStaticFinal
-
/** There was a bit of a gordian logic knot here regarding forwarders.
* All we really have to do is exclude certain categories of symbols and
* then all matching names.
@@ -1035,7 +1030,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
for (m <- moduleClass.info.nonPrivateMembers) {
if (shouldForward(m)) {
log("Adding static forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
- addForwarder(jclass, moduleClass, m, accessFlags)
+ addForwarder(jclass, moduleClass, m)
}
else debuglog("No forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
}
diff --git a/test/files/run/bug4827.scala b/test/files/run/bug4827.scala
new file mode 100644
index 0000000000..7270cf169d
--- /dev/null
+++ b/test/files/run/bug4827.scala
@@ -0,0 +1,15 @@
+object Test {
+ def main(args: Array[String]): Unit = Foo.foo()
+}
+
+trait CommonTrait {
+ def foo(): String = null
+}
+
+class Foo
+
+object Foo {
+ def goo() = new Foo() with CommonTrait
+
+ def foo(): String = null
+}
diff --git a/test/files/run/bug4827b.scala b/test/files/run/bug4827b.scala
new file mode 100644
index 0000000000..84d6d907d3
--- /dev/null
+++ b/test/files/run/bug4827b.scala
@@ -0,0 +1,18 @@
+package foo {
+ class Foo { }
+ object Foo {
+ def bippy(x: Int) = x
+ }
+}
+
+package bar {
+ class Bippy extends foo.Foo {
+ def bippy(x: Int) = x
+ }
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ new bar.Bippy bippy 5
+ }
+}