diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-28 07:04:26 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-28 07:04:26 +0000 |
commit | 892ecd2db75cb41cbcb582c26c2a7b32186625c0 (patch) | |
tree | ef7a68a88f4e2cbb4506afdf7f076f6119a2365c | |
parent | 5dbb616610b616bff7ec8bb9b78a6f8a59203d7d (diff) | |
download | scala-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.scala | 19 | ||||
-rw-r--r-- | test/files/run/bug4827.scala | 15 | ||||
-rw-r--r-- | test/files/run/bug4827b.scala | 18 |
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 + } +} |