Skip to content

Pattern match in constructor results in extra class member #1913

Open
@scabug

Description

@scabug

The compiler generates an extra member (a tuple) for the following class as can be seen from the generated byte code below.
The extra field is:

private final scala.Tuple3 x$$2;

Here is the class definition:

final class C(i: Int, j: Int, k: Int)
{
  val (m_i, m_j, m_k) = (i + 3, j + 7, k - j)

  override def toString: String =
  {
    "(" + m_i + ", " + m_j + ", " + m_k + ")"
  }
}

And here is the generated bytecode:

public final class math.C extends java.lang.Object implements scala.ScalaObject{
private final int m_k;

private final int m_j;

private final int m_i;

private final scala.Tuple3 x$$2;

public math.C(int, int, int);
  Code:
   0:   aload_0
   1:   invokespecial   SI-17; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   iload_1
   6:   iconst_3
   7:   iadd
   8:   istore  4
   10:  iload_2
   11:  ldc     SI-18; //int 7
   13:  iadd
   14:  istore  5
   16:  iload_3
   17:  iload_2
   18:  isub
   19:  istore  6
   21:  new     SI-20; //class scala/Tuple3
   24:  dup
   25:  iload   4
   27:  invokestatic    SI-26; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
   30:  iload   5
   32:  invokestatic    SI-26; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
   35:  iload   6
   37:  invokestatic    SI-26; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
   40:  invokespecial   SI-29; //Method scala/Tuple3."<init>":(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
   43:  putfield        SI-33; //Field x$$2:Lscala/Tuple3;
   46:  aload_0
   47:  aload_0
   48:  getfield        SI-33; //Field x$$2:Lscala/Tuple3;
   51:  invokevirtual   SI-37; //Method scala/Tuple3._1:()Ljava/lang/Object;
   54:  invokestatic    SI-41; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   57:  putfield        SI-43; //Field m_i:I
   60:  aload_0
   61:  aload_0
   62:  getfield        SI-33; //Field x$$2:Lscala/Tuple3;
   65:  invokevirtual   SI-46; //Method scala/Tuple3._2:()Ljava/lang/Object;
   68:  invokestatic    SI-41; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   71:  putfield        SI-48; //Field m_j:I
   74:  aload_0
   75:  aload_0
   76:  getfield        SI-33; //Field x$$2:Lscala/Tuple3;
   79:  invokevirtual   SI-51; //Method scala/Tuple3._3:()Ljava/lang/Object;
   82:  invokestatic    SI-41; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   85:  putfield        SI-53; //Field m_k:I
   88:  return

As a general comment on the language itself, I find the feature of class constructors as one of the least thought out parts of the Scala language. Maybe it's because I am new to the language but it's never clear what becomes a field and what doesn't. Also the inability to use local variables in the class constructor (because it will/may become a member variable) is very troubling and restrictive. Basically one is forced to always use the factory pattern (in a companion object) so as to be sure what is going on and so any savings (in conciseness) from the class-constructor feature is nullified.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bytecodefixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions