Skip to content

ArrayOps.transpose NPE when using asArray #13178

@bluelhf

Description

@bluelhf

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions