scala-native / scala-native

Your favorite language gets closer to bare metal.
http://scala-native.org
Other
4.5k stars 364 forks source link

j.u.ArrayList.toArray* needs attention #1695

Open LeeTibbert opened 5 years ago

LeeTibbert commented 5 years ago

After Issue #1694, j.l.System.arraycopy gets fixed, the two toArray() methods in java.util.ArrayList.scala should be closely reviewed for correct behavior and performance.The test in ArrayListSuite.scala currently marked testFails should be enabled (changed to test and issue number deleted).

ekrich commented 4 years ago

The follow runs on Scastie, no ArrayStoreException.

import java.util.ArrayList

class NotSuperClass
class SubClass
val al1 = new ArrayList[SubClass]()
al1.toArray(Array.empty[NotSuperClass])
// result Array[NotSuperClass]
LeeTibbert commented 4 years ago

Ah! 'Tis a cleaver & slippery beast, this our Snark is... The testFails in ArrayDequeSuite in PR #1696 mentioned in the base note, Note that there are two cases:

testFails("toArray(a: Array[T]) - throws ArrayStoreException when not " + "T >: E", 1694) { class NotSuperClass class SubClass

locally { // This passes on Scala JVM
  val ad = new ArrayList[SubClass]()

  ad.toArray(Array.empty[NotSuperClass])
}

locally { // This is the case which is failing on ScalaNative.
  // The difference is that this Deque is not Empty.
  val ad = new ArrayDeque(Seq(new SubClass).asJava)

  assertThrows[ArrayStoreException] {
    ad.toArray(Array.empty[NotSuperClass])
  }
}

} }

More to the point, from your example, using scala 2.12 from Sbt console, should reproduce on Scastie:

scala> class NotSuperClass defined class NotSuperClass

scala> class SubClass defined class SubClass

scala> val al1 = new ArrayList[SubClass]() al1: java.util.ArrayList[SubClass] = []

scala> al1.toArray(Array.empty[NotSuperClass]) res0: Array[NotSuperClass] = Array()

scala> al1.add(new SubClass) res1: Boolean = true

scala> al1.toArray(Array.empty[NotSuperClass]) java.lang.ArrayStoreException at java.util.Arrays.copyOf(Arrays.java:3213) at java.util.ArrayList.toArray(ArrayList.java:413) ... 31 elided


QED?