You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mixin fields with trait setters shouldn't be JVM final
Before:
```
scala> trait T { val foo = 24 }; class C extends T
defined trait T
defined class C
scala> :javap -private -c C
Compiled from "<console>"
public class $line3.$read$$iw$$iw$C implements $line3.$read$$iw$$iw$T {
private final int foo;
public int foo();
Code:
0: aload_0
1: getfield #21 // Field foo:I
4: ireturn
public void $line3$$read$$iw$$iw$T$_setter_$foo_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #21 // Field foo:I
5: return
public $line3.$read$$iw$$iw$C();
Code:
0: aload_0
1: invokespecial #30 // Method java/lang/Object."<init>":()V
4: aload_0
5: invokestatic #34 // InterfaceMethod $line3/$read$$iw$$iw$T.$init$:(L$line3/$read$$iw$$iw$T;)V
8: return
}
```
The assignment to the final field `foo` has always contravened the JVM spec,
and this rule is enforced for any classfiles of format 53 and higher.
After this patch:
```
scala> trait T { val foo = 24 }; class C extends T
defined trait T
defined class C
scala> :javap -private -c C
Compiled from "<console>"
public class $line3.$read$$iw$$iw$C implements $line3.$read$$iw$$iw$T {
private int foo;
public int foo();
Code:
0: aload_0
1: getfield #21 // Field foo:I
4: ireturn
public void $line3$$read$$iw$$iw$T$_setter_$foo_$eq(int);
Code:
0: aload_0
1: iload_1
2: putfield #21 // Field foo:I
5: return
public $line3.$read$$iw$$iw$C();
Code:
0: aload_0
1: invokespecial #30 // Method java/lang/Object."<init>":()V
4: aload_0
5: invokestatic #34 // InterfaceMethod $line3/$read$$iw$$iw$T.$init$:(L$line3/$read$$iw$$iw$T;)V
8: getstatic #40 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
11: invokevirtual #43 // Method scala/runtime/ScalaRunTime$.releaseFence:()V
14: return
}
```
0 commit comments