-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
itype:bugstat:needs triageEvery issue needs to have an "area" and "itype" labelEvery issue needs to have an "area" and "itype" label
Description
Compiler version
3.7.4
Minimized code
object PairProblem {
def f0(x: Int, y: Int): (Int, Int) =
val p = (x, y)
p
def f1(x: Int, y: Int): (Int, Int) =
val p = x -> y
p
}Output
Naively I assumed the code produced by the two functions above would be identical but alas it's not.
For f0 we get what one would expect. But f1 looks quite different. First, the first integer is boxed, we then create
an instance of class ArrowAssoc, then box the other integer, and finally call the -> method on object we created. So we build 4 objects, instead of 1 as the other method does. All in all 14 bytecode instructions vs 8.
The strange thing is that ArrowAssoc inherits from AnyVal and -> appears to be declared inline neither of
which appears to be doing anything (I show their defs below).
public f0(II)Lscala/Tuple2;
// parameter final x
// parameter final y
L0
LINENUMBER 5 L0
NEW scala/Tuple2$mcII$sp
DUP
ILOAD 1
ILOAD 2
INVOKESPECIAL scala/Tuple2$mcII$sp.<init> (II)V
ASTORE 3
L1
LINENUMBER 7 L1
ALOAD 3
ARETURN
L2
LOCALVARIABLE p Lscala/Tuple2; L1 L2 3
LOCALVARIABLE this Lneo/com/PairProblem$; L0 L2 0
LOCALVARIABLE x I L0 L2 1
LOCALVARIABLE y I L0 L2 2
MAXSTACK = 4
MAXLOCALS = 4
// access flags 0x1
// signature (II)Lscala/Tuple2<Ljava/lang/Object;Ljava/lang/Object;>;
// declaration: scala.Tuple2<java.lang.Object, java.lang.Object> f1(int, int)
public f1(II)Lscala/Tuple2;
// parameter final x
// parameter final y
L0
LINENUMBER 10 L0
GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
ILOAD 1
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/Predef$.ArrowAssoc (Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 4
GETSTATIC scala/Predef$ArrowAssoc$.MODULE$ : Lscala/Predef$ArrowAssoc$;
ALOAD 4
ILOAD 2
INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
INVOKEVIRTUAL scala/Predef$ArrowAssoc$.$minus$greater$extension (Ljava/lang/Object;Ljava/lang/Object;)Lscala/Tuple2;
ASTORE 3
L1
LINENUMBER 12 L1
ALOAD 3
ARETURN
L2
LOCALVARIABLE p Lscala/Tuple2; L1 L2 3
LOCALVARIABLE this Lneo/com/PairProblem$; L0 L2 0
LOCALVARIABLE x I L0 L2 1
LOCALVARIABLE y I L0 L2 2
MAXSTACK = 3
MAXLOCALS = 5Here is the def of ArrowAssoc from the standard lib:
implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
@inline def -> [B](y: B): (A, B) = (self, y)
@deprecated("Use `->` instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code.", "2.13.0")
def →[B](y: B): (A, B) = ->(y)
}Expectation
The code produced should be identical.
Metadata
Metadata
Assignees
Labels
itype:bugstat:needs triageEvery issue needs to have an "area" and "itype" labelEvery issue needs to have an "area" and "itype" label