summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-02-15 14:14:13 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-02-15 14:14:13 +0100
commit640e27950001d6eddca89654b93e042a38822557 (patch)
treec2f21f40c282d0933b5c40c8ae156c66c56d88c7 /src/compiler
parent45cfc7b3a242f0be0397c5eb3946356bf3446dc9 (diff)
downloadscala-640e27950001d6eddca89654b93e042a38822557.tar.gz
scala-640e27950001d6eddca89654b93e042a38822557.tar.bz2
scala-640e27950001d6eddca89654b93e042a38822557.zip
SI-3452 A better fix for static forwarder generic sigs
The previous commit fixed this in the wrong way. The addition to the test case (testing an inherited method from a base class in addition to the test with a mxin method) still failed. Like mixin, static forwarder generation uses the exact erased siganture of the forwardee for the forwarder. It really ought to use the as-seen-from signature (adding requisite boxing/ unboxing), but until we do that we have to avoid emitting generic signatures that are incoherent.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala36
1 files changed, 21 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index b276572f9b..0474482db9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -821,15 +821,32 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
def getCurrentCUnit(): CompilationUnit
+ final def staticForwarderGenericSignature(sym: Symbol, moduleClass: Symbol): String = {
+ if (sym.isDeferred) null // only add generic signature if method concrete; bug #1745
+ else {
+ // SI-3452 Static forwarder generation uses the same erased signature as the method if forwards to.
+ // By rights, it should use the signature as-seen-from the module class, and add suitable
+ // primitive and value-class boxing/unboxing.
+ // But for now, just like we did in mixin, we just avoid writing a wrong generic signature
+ // (one that doesn't erase to the actual signature). See run/t3452b for a test case.
+ val memberTpe = enteringErasure(moduleClass.thisType.memberInfo(sym))
+ val erasedMemberType = erasure.erasure(sym)(memberTpe)
+ if (erasedMemberType =:= sym.info)
+ getGenericSignature(sym, moduleClass, memberTpe)
+ else null
+ }
+ }
+
/** @return
* - `null` if no Java signature is to be added (`null` is what ASM expects in these cases).
* - otherwise the signature in question
*/
def getGenericSignature(sym: Symbol, owner: Symbol): String = {
-
- if (!needsGenericSignature(sym)) { return null }
-
val memberTpe = enteringErasure(owner.thisType.memberInfo(sym))
+ getGenericSignature(sym, owner, memberTpe)
+ }
+ def getGenericSignature(sym: Symbol, owner: Symbol, memberTpe: Type): String = {
+ if (!needsGenericSignature(sym)) { return null }
val jsOpt: Option[String] = erasure.javaSig(sym, memberTpe)
if (jsOpt.isEmpty) { return null }
@@ -1064,18 +1081,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
)
// TODO needed? for(ann <- m.annotations) { ann.symbol.initialize }
- val jgensig = (
- // only add generic signature if method concrete; bug #1745
- if (m.isDeferred) null else {
- val clazz = module.linkedClassOfClass
- val m1 = (
- if ((clazz.info member m.name) eq NoSymbol)
- enteringErasure(m.cloneSymbol(clazz, Flags.METHOD | Flags.STATIC))
- else m
- )
- getGenericSignature(m1, clazz)
- }
- )
+ val jgensig = staticForwarderGenericSignature(m, module)
addRemoteExceptionAnnot(isRemoteClass, hasPublicBitSet(flags), m)
val (throws, others) = m.annotations partition (_.symbol == ThrowsClass)
val thrownExceptions: List[String] = getExceptions(throws)