Open
Description
Compiler version
scalaVersion := "3.6.2"
Minimized code
def h(x: Int) = 2 * x + 1
def f(x0: Int, y0: Int): Int =
val (x1, y1) = (h(x0), h(y0))
x1 + y1
Output
public f(II)I
// parameter final x0
// parameter final y0
L0
LINENUMBER 100 L0
GETSTATIC scala/Tuple2$.MODULE$ : Lscala/Tuple2$;
ALOAD 0
ILOAD 1
INVOKEVIRTUAL app/Utils$.h (I)I
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
ALOAD 0
ILOAD 2
INVOKEVIRTUAL app/Utils$.h (I)I
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/Tuple2$.apply (Ljava/lang/Object;Ljava/lang/Object;)Lscala/Tuple2;
ASTORE 3
ALOAD 3
INVOKEVIRTUAL scala/Tuple2._1$mcI$sp ()I
ISTORE 4
L1
ALOAD 3
INVOKEVIRTUAL scala/Tuple2._2$mcI$sp ()I
ISTORE 5
L2
LINENUMBER 102 L2
ILOAD 4
ILOAD 5
IADD
IRETURN
Expectation
The pattern match can never fail, and yet the compiler is blind to it, and goes around building pairs only to deconstruct them a moment later. The code is correct, but it's just insanity -- too long, much less likely to be inlined anywhere etc. Maybe the jvm can do something or other (put the pair on the stack, inline the deconstructor etc.), but more likely than not, it will always be slower than:
val x1 = h(x0)
val x2 = h(x1)
which is what the compiler ought to produce in the first place.