@@ -806,7 +806,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
806806 */
807807 private def addForwarder (
808808 isRemoteClass : Boolean ,
809- isBridge : Boolean ,
810809 jclass : asm.ClassVisitor ,
811810 moduleClass : Symbol ,
812811 m : Symbol ): Unit = {
@@ -834,7 +833,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
834833 */
835834 // TODO: evaluate the other flags we might be dropping on the floor here.
836835 val flags = GenBCode .PublicStatic |
837- (if (isBridge) asm.Opcodes .ACC_BRIDGE else 0 ) |
838836 (if (m.isVarargsMethod) asm.Opcodes .ACC_VARARGS else 0 ) |
839837 (if (m.isDeprecated) asm.Opcodes .ACC_DEPRECATED else 0 )
840838
@@ -887,32 +885,23 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
887885 */
888886 def addForwarders (isRemoteClass : Boolean , jclass : asm.ClassVisitor , jclassName : String , moduleClass : Symbol ) {
889887 assert(moduleClass.isModuleClass, moduleClass)
890- debuglog(s " Dumping mirror class for object: $moduleClass" )
891888
892- val linkedClass = moduleClass.companionClass
889+ val linkedClass = moduleClass.companionClass
893890 lazy val conflictingNames : Set [Name ] = {
894891 (linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name }).toSet
895892 }
896- debuglog(s " Potentially conflicting names for forwarders: $conflictingNames" )
897-
898- for (m <- moduleClass.info.membersBasedOnFlags(BCodeHelpers .ExcludedForwarderFlags , symtab.Flags .METHOD )) {
899- // Fix for scala/bug#11207, see https://github.com/scala/scala/pull/7035/files#r226274350. This makes sure that 2.12.8 generates
900- // the same forwarder methods as in 2.12.6 (but includes bridge flags). In 2.13 we don't generate any forwarders for bridges.
901- val bridgeImplementingAbstract = m.isBridge && m.nextOverriddenSymbol.isDeferred
902- if (m.isType || m.isDeferred || bridgeImplementingAbstract || (m.owner eq definitions.ObjectClass ) || m.isConstructor)
903- debuglog(s " No forwarder for ' $m' from $jclassName to ' $moduleClass': ${m.isType} || ${m.isDeferred} || ${m.owner eq definitions.ObjectClass } || ${m.isConstructor}" )
904- else if (conflictingNames(m.name))
905- log(s " No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}" )
906- else if (m.hasAccessBoundary)
907- log(s " No forwarder for non-public member $m" )
908- else {
909- log(s " Adding static forwarder for ' $m' from $jclassName to ' $moduleClass' " )
910- addForwarder(isRemoteClass,
911- isBridge = m.isBridge,
912- jclass,
913- moduleClass,
914- m)
915- }
893+
894+ // Before erasure * to exclude bridge methods. Excluding them by flag doesn't work, because then
895+ // the method from the base class that the bridge overrides is included (scala/bug#10812).
896+ // * Using `exitingUncurry` (not `enteringErasure`) because erasure enters bridges in traversal,
897+ // not in the InfoTransform, so it actually modifies the type from the previous phase.
898+ // Uncurry adds java varargs, which need to be included in the mirror class.
899+ val members = exitingUncurry(moduleClass.info.membersBasedOnFlags(BCodeHelpers .ExcludedForwarderFlags , symtab.Flags .METHOD ))
900+ for (m <- members) {
901+ val excl = m.isDeferred || m.isConstructor || m.hasAccessBoundary ||
902+ { val o = m.owner; (o eq ObjectClass ) || (o eq AnyRefClass ) || (o eq AnyClass ) } ||
903+ conflictingNames(m.name)
904+ if (! excl) addForwarder(isRemoteClass, jclass, moduleClass, m)
916905 }
917906 }
918907
@@ -1184,14 +1173,9 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
11841173}
11851174
11861175object BCodeHelpers {
1187- val ExcludedForwarderFlags = {
1176+ val ExcludedForwarderFlags : Long = {
11881177 import scala .tools .nsc .symtab .Flags ._
1189- // Should include DEFERRED but this breaks findMember.
1190- // Note that BRIDGE is *not* excluded. Trying to exclude bridges by flag doesn't work, findMembers
1191- // will then include the member from the parent (which the bridge overrides / implements).
1192- // This caused scala/bug#11061 and scala/bug#10812. In 2.13, they are fixed by not emitting
1193- // forwarders for bridges. But in 2.12 that's not binary compatible, so instead we continue to
1194- // emit forwarders for bridges, but mark them with ACC_BRIDGE.
1178+ // Don't include DEFERRED but filter afterwards, see comment on `findMembers`
11951179 SPECIALIZED | LIFTED | PROTECTED | STATIC | EXPANDEDNAME | PRIVATE | MACRO
11961180 }
11971181
0 commit comments