Skip to content

Commit cfd91d4

Browse files
Merge pull request scala#15707 from WojciechMazur/fix/i10835-final-vars
Set ACC_FINAL access flag to final variable accessors
2 parents da2d44a + 51be2dd commit cfd91d4

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes {
310310
// tests/run/serialize.scala and https://github.com/typelevel/cats-effect/pull/2360).
311311
val privateFlag = !sym.isClass && (sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass))
312312

313-
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable) && !sym.enclosingClass.is(Trait)
313+
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable, butNot = Accessor) && !sym.enclosingClass.is(Trait)
314314

315315
import asm.Opcodes._
316316
import GenBCodeOps.addFlagIf

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,29 @@ class DottyBytecodeTests extends DottyBytecodeTest {
15571557
}
15581558
}
15591559

1560+
/** Check that final mutable var accessors are final */
1561+
@Test def i10835 = {
1562+
val source =
1563+
s"""class A {
1564+
| final var x = 1
1565+
|}
1566+
|""".stripMargin
1567+
checkBCode(source){dir =>
1568+
val clsIn = dir.lookupName("A.class", directory = false).input
1569+
val clsNode = loadClassNode(clsIn)
1570+
def isFinal(access: Int) = (access & Opcodes.ACC_FINAL) != 0
1571+
1572+
val field = clsNode.fields.asScala.find(_.name == "x").map(_.access)
1573+
assertTrue("field is not final", field.exists(!isFinal(_)))
1574+
assertTrue("field is private", field.exists(acc => (acc & Opcodes.ACC_PRIVATE) != 0))
1575+
1576+
val methods = clsNode.methods.asScala
1577+
def methodAccess(name: String) = methods.find(_.name == name).map(_.access)
1578+
assertTrue("getter is final", methodAccess("x").exists(isFinal))
1579+
assertTrue("setter is final", methodAccess("x_$eq").exists(isFinal))
1580+
}
1581+
}
1582+
15601583
/** Check that erasure if `Int | Nothing` is `int` */
15611584
@Test def i14970 = {
15621585
val source =

0 commit comments

Comments
 (0)