bug
bug copied to clipboard
ClassFormatError with local definitions
The following produces a bad classfile, both with 2.9.1 and latest nightly.
object test {
def main(args: Array[String]): Unit = {
var out = 1
trait Trait {
def foo(): Unit = {
out += 1
}
}
case class C(parent: Trait) extends Trait {}
C(null)
}
}
test.main(Array())
Error is: java.lang.ClassFormatError: Duplicate field name&signature in class file test$C$2
Imported From: https://issues.scala-lang.org/browse/SI-5252?orig=1 Reporter: @lrytz Affected Versions: 2.11.0-M8, 2.12.0 See #1960, #3994
@lrytz said: that's the only other ticket that has the same error message
@retronym said: Reduced a step or two:
object Test {
{
val out = 0
trait Trait {
def foo {
out
}
}
class C extends Trait {
def copy { new C }
}
new C
}
def main(args: Array[String]) {
}
}
@retronym said: Seems to be a regression fro 2.7.7 to 2.8.0.
@magarciaEPFL said:
Right after flatten there are two field declarations with the same name and type (val out$1: Int = _; ), one each in the following classes:
class Test$C$1 extends Object with Test$Trait$1abstract trait Test$Trait$1$class extends Object with Test$Trait$1
class Test$C$1 extends Object with Test$Trait$1 {
def copy(): Unit = {
new Test$C$1(Test$C$1.this.out$1);
()
};
<synthetic> <paramaccessor> private[this] val out$1: Int = _; /* <---------------- in the composed class */
def <init>(out$1: Int): Test$C$1 = {
Test$C$1.this.out$1 = out$1;
Test$C$1.super.<init>();
Test$C$1.this.$asInstanceOf[Test$Trait$1$class]()./*Test$Trait$1$class*/$init$(out$1);
()
}
};
abstract trait Test$Trait$1$class extends Object with Test$Trait$1 {
def foo(): Unit = {
Test$Trait$1$class.this.out$1;
()
};
<synthetic> <paramaccessor> private[this] val out$1: Int = _; /* <---------------- in the implementation class */
def /*Test$Trait$1$class*/$init$(out$1: Int): Unit = {
Test$Trait$1$class.this.out$1 = out$1;
()
}
}
The Mixin phase lumps both fields in class Test$C$1
class Test$C$1 extends Object with Test$Trait$1 {
<synthetic> <stable> <accessor> <paramaccessor> def out$1(): Int = Test$C$1.this.out$1; /* <---------------- (1 of 2) */
private[this] val out$1: Int = _;
<synthetic> <accessor> <paramaccessor> def Test$Trait$1$_setter_$out$1_=(x$1: Int): Unit = Test$C$1.this.out$1 = x$1;
def foo(): Unit = Test$Trait$1$class.foo(Test$C$1.this);
def copy(): Unit = {
new Test$C$1(Test$C$1.this.out$1);
()
};
<synthetic> <paramaccessor> private[this] val out$1: Int = _; /* <---------------- (2 of 2) */
def <init>(out$1: Int): Test$C$1 = {
Test$C$1.this.out$1 = out$1;
Test$C$1.super.<init>();
Test$Trait$1$class./*Test$Trait$1$class*/$init$(Test$C$1.this, out$1);
()
}
}
That's why javap -private Test\$C\$1 shows:
public class Test$C$1 extends java.lang.Object implements Test$Trait$1{
private final int out$1;
private final int out$1;
public int out$1();
public void Test$Trait$1$_setter_$out$1_$eq(int);
public void foo();
public void copy();
public Test$C$1(int);
}
@retronym said: More mangling seems to be called for here. Might be worth considering #3994 at the same time.
@lrytz said: 2.12.0-RC1 gives an error message:
A.scala:60: error: parameter 'out$1' requires field but conflicts with value out$1 in trait Trait$1
var out = 1
^
one error found
@lrytz said: Another test case: http://stackoverflow.com/questions/39635543/method-in-sealed-trait-gives-duplicate-field-name-signature-in-class-file
Just want to chime in that I am getting the "duplicate field name&signature" issue in Scala 2.12.x with code that has worked flawlessly for a long time in Scala 2.11.x. Things seems to be worse in 2.12 than they were in 2.11.
#8984 has an additional reproduction