Skip to content

Commit 5359574

Browse files
authored
Merge pull request #6352 from dotty-staging/fix-final-bridge
Don't emit mixin forwarders as final
2 parents 1e63a17 + 700eea7 commit 5359574

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,21 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes {
200200

201201
val finalFlag = sym.getsJavaFinalFlag
202202

203-
// Primitives are "abstract final" to prohibit instantiation
204-
// without having to provide any implementations, but that is an
205-
// illegal combination of modifiers at the bytecode level so
206-
// suppress final if abstract if present.
207203
import asm.Opcodes._
208204
GenBCodeOps.mkFlags(
209205
if (privateFlag) ACC_PRIVATE else ACC_PUBLIC,
210206
if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0,
211207
if (sym.isInterface) ACC_INTERFACE else 0,
212-
if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0,
208+
209+
if (finalFlag &&
210+
// Primitives are "abstract final" to prohibit instantiation
211+
// without having to provide any implementations, but that is an
212+
// illegal combination of modifiers at the bytecode level so
213+
// suppress final if abstract if present.
214+
!sym.hasAbstractFlag &&
215+
// Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks
216+
!sym.isBridge)
217+
ACC_FINAL else 0,
213218
if (sym.isStaticMember) ACC_STATIC else 0,
214219
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
215220
if (sym.isArtifact) ACC_SYNTHETIC else 0,

tests/run/t11485.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import java.lang.reflect.Modifier
2+
3+
trait HaveFinalMethod {
4+
final def finalMethod: String = "final"
5+
}
6+
7+
class Child extends HaveFinalMethod
8+
9+
object Test {
10+
def main(args: Array[String]): Unit = {
11+
val meth = classOf[Child].getMethod("finalMethod")
12+
assert(meth.isBridge)
13+
val mods = meth.getModifiers
14+
assert(!Modifier.isFinal(mods))
15+
}
16+
}

0 commit comments

Comments
 (0)