Closed
Description
scala> class ArrayLength { def test[T](a: Array[T]) = a match { case x: Array[AnyRef] => x.length }}
defined class ArrayLength
scala> :javap -c ArrayLength#test
public <T> int test(java.lang.Object);
Code:
0: aload_1
1: astore_3
2: aload_3
3: instanceof #18 // class "[Ljava/lang/Object;"
6: ifeq 27
9: aload_3
10: checkcast #18 // class "[Ljava/lang/Object;"
13: astore 4
15: getstatic #24 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
18: aload 4
20: invokevirtual #27 // Method scala/runtime/ScalaRunTime$.array_length:(Ljava/lang/Object;)I
23: istore_2
24: goto 39
27: goto 30
30: new #29 // class scala/MatchError
33: dup
34: aload_3
35: invokespecial #33 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
38: athrow
39: iload_2
40: ireturn
Workaround is to upcast:
scala> class ArrayLength1 { def test[T](a: Array[T]) = a match { case x: Array[AnyRef] => (x: Array[AnyRef]).length }}
defined class ArrayLength1
scala> :javap -c ArrayLength1#test
public <T> int test(java.lang.Object);
Code:
0: aload_1
1: astore_3
2: aload_3
3: instanceof #18 // class "[Ljava/lang/Object;"
6: ifeq 22
9: aload_3
10: checkcast #18 // class "[Ljava/lang/Object;"
13: astore 4
15: aload 4
17: arraylength
18: istore_2
19: goto 34
22: goto 25
25: new #20 // class scala/MatchError
28: dup
29: aload_3
30: invokespecial #24 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
33: athrow
34: iload_2
35: ireturn
The proper fix would be in https://github.com/scala/scala/blob/179f9a97f29319b29f74a61e02d0a6e87114bac0/src/reflect/scala/reflect/internal/transform/Erasure.scala#L61