Skip to content

Commit 1e1a162

Browse files
authored
Merge pull request scala#7383 from lrytz/b11207
No static forwarders for bridges implementing abstract methods
2 parents 85a82b0 + 8afd256 commit 1e1a162

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,10 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
896896
debuglog(s"Potentially conflicting names for forwarders: $conflictingNames")
897897

898898
for (m <- moduleClass.info.membersBasedOnFlags(BCodeHelpers.ExcludedForwarderFlags, symtab.Flags.METHOD)) {
899-
if (m.isType || m.isDeferred || (m.owner eq definitions.ObjectClass) || m.isConstructor)
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)
900903
debuglog(s"No forwarder for '$m' from $jclassName to '$moduleClass': ${m.isType} || ${m.isDeferred} || ${m.owner eq definitions.ObjectClass} || ${m.isConstructor}")
901904
else if (conflictingNames(m.name))
902905
log(s"No forwarder for $m due to conflict with ${linkedClass.info.member(m.name)}")

test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,28 @@ class BytecodeTest extends BytecodeTesting {
1616
import compiler._
1717

1818
@Test
19-
def bridgeFlag(): Unit = {
19+
def staticForwardersBridgeFlag(): Unit = {
2020
val code =
21-
""" A { def f: Object = null }
22-
|object B extends A { override def f: String = "b" }
21+
""" A {
22+
| def f: Object = null
23+
| def g: Object
24+
|}
25+
|object B extends A {
26+
| override def f: String = "b" // "bridge" forwarder
27+
| def g: String = "b" // no "bridge" forwarder, as the overridden method is abstract, scala/bug#11207
28+
|}
29+
|case class K(x: Int, s: String)
2330
""".stripMargin
24-
for (base <- List("trait", "class")) {
25-
val List(a, bMirror, bModule) = compileClasses(base + code)
31+
for (base <- List("trait", "abstract class")) {
32+
val List(a, bMirror, bModule, kClass, kModule) = compileClasses(base + code)
2633
assertEquals("B", bMirror.name)
27-
assertEquals(List("f()Ljava/lang/Object;0x49", "f()Ljava/lang/String;0x9"),
34+
assertEquals(List("f()Ljava/lang/Object;0x49", "f()Ljava/lang/String;0x9", "g()Ljava/lang/String;0x9"),
2835
bMirror.methods.asScala
29-
.filter(_.name == "f")
36+
.filter(m => m.name == "f" || m.name == "g")
3037
.map(m => m.name + m.desc + "0x" + Integer.toHexString(m.access)).toList.sorted)
38+
assertEquals("K", kClass.name)
39+
val List(app) = kClass.methods.asScala.filter(_.name == "apply").toList
40+
assertEquals("apply(ILjava/lang/String;)LK;0x9", app.name + app.desc + "0x" + Integer.toHexString(app.access))
3141
}
3242
}
3343

0 commit comments

Comments
 (0)