When transposing an array of non-arrays (e.g. Array[Object]) using transpose's asArray parameter to convert the objects to arrays, the method fails and produces a NullPointerException instead. For empty arrays, it produces an array of the incorrect type.
Reproduction steps
Scala version: 2.13.19 (at commit 2987773)
scala> Array(new Object()).transpose(_ => Array(1))
java.lang.NullPointerException: Cannot read field "classValueMap" because "type" is null
at java.base/java.lang.ClassValue.getCacheCarefully(ClassValue.java:183)
at java.base/java.lang.ClassValue.get(ClassValue.java:139)
at scala.runtime.ClassValueCompat.get(ClassValueCompat.scala:33)
at scala.reflect.ClassTag$.apply(ClassTag.scala:157)
at scala.collection.ArrayOps$.mkRowBuilder$1(ArrayOps.scala:1303)
at scala.collection.ArrayOps$.transpose$extension(ArrayOps.scala:1304)
... 57 elided
scala> val array: Array[Array[Int]] = Array().transpose((_: Object) => Array(1))
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [[I ([Ljava.lang.Object; and [[I are in module java.base of loader 'bootstrap')
... 57 elided
scala> Seq(new Object()).transpose(_ => Seq(1)) // Equivalent IterableOps method works.
val res1: Seq[Seq[Int]] = List(List(1))
scala>
Problem
I would expect Array(Array(1)). The problem occurs because ArrayOps.transpose creates its array builder's class tag using the component type of the outer array rather than the return type of asArray.
Additional Information
I have written a patch that fixes the bug for non-empty arrays without altering the existing API. I don't think it's possible to fix the method's behaviour on empty arrays without introducing a class tag parameter (since there is no element to give to asArray for determining the class tag).
The underlying problem is that ArrayOps does not have access to a class tag for B, and so it has only ever been a best guess at the correct array type.
https://github.com/scala/scala/blob/29877738984789c487a2834a574d7f195080622c/src/library/scala/collection/ArrayOps.scala#L1295-L1304
When transposing an array of non-arrays (e.g.
Array[Object]) usingtranspose'sasArrayparameter to convert the objects to arrays, the method fails and produces a NullPointerException instead. For empty arrays, it produces an array of the incorrect type.Reproduction steps
Scala version: 2.13.19 (at commit 2987773)
Problem
I would expect
Array(Array(1)). The problem occurs becauseArrayOps.transposecreates its array builder's class tag using the component type of the outer array rather than the return type ofasArray.Additional Information
I have written a patch that fixes the bug for non-empty arrays without altering the existing API. I don't think it's possible to fix the method's behaviour on empty arrays without introducing a class tag parameter (since there is no element to give to
asArrayfor determining the class tag).The underlying problem is that ArrayOps does not have access to a class tag for
B, and so it has only ever been a best guess at the correct array type.https://github.com/scala/scala/blob/29877738984789c487a2834a574d7f195080622c/src/library/scala/collection/ArrayOps.scala#L1295-L1304