diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-02-15 14:14:13 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-02-15 14:14:13 +0100 |
commit | 640e27950001d6eddca89654b93e042a38822557 (patch) | |
tree | c2f21f40c282d0933b5c40c8ae156c66c56d88c7 /src | |
parent | 45cfc7b3a242f0be0397c5eb3946356bf3446dc9 (diff) | |
download | scala-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')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 36 |
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) |