Skip to content

Commit 6666180

Browse files
authored
Merge pull request scala/scala#6829 from retronym/topic/array-copy-of
Deal with special case for Array[Unit] in Array.{copyOf,copyAs}
2 parents dc60965 + 5327ad6 commit 6666180

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

library/src/scala/Array.scala

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import mutable.ArrayBuilder
1414
import immutable.ArraySeq
1515
import scala.language.implicitConversions
1616
import scala.reflect.ClassTag
17-
import scala.runtime.ScalaRunTime
17+
import scala.runtime.{BoxedUnit, ScalaRunTime}
1818
import scala.runtime.ScalaRunTime.{array_apply, array_update}
1919

2020
/** Utility methods for operating on arrays.
@@ -122,6 +122,7 @@ object Array {
122122
* @see `java.util.Arrays#copyOf`
123123
*/
124124
def copyOf[A](original: Array[A], newLength: Int): Array[A] = (original match {
125+
case x: Array[BoxedUnit] => newUnitArray(newLength).asInstanceOf[Array[A]]
125126
case x: Array[AnyRef] => java.util.Arrays.copyOf(x, newLength)
126127
case x: Array[Int] => java.util.Arrays.copyOf(x, newLength)
127128
case x: Array[Double] => java.util.Arrays.copyOf(x, newLength)
@@ -131,10 +132,6 @@ object Array {
131132
case x: Array[Byte] => java.util.Arrays.copyOf(x, newLength)
132133
case x: Array[Short] => java.util.Arrays.copyOf(x, newLength)
133134
case x: Array[Boolean] => java.util.Arrays.copyOf(x, newLength)
134-
case x: Array[Unit] =>
135-
val dest = new Array[Unit](newLength)
136-
Array.copy(original, 0, dest, 0, original.length)
137-
dest
138135
}).asInstanceOf[Array[A]]
139136

140137
/** Copy one array to another, truncating or padding with default values (if
@@ -151,20 +148,30 @@ object Array {
151148
* @see `java.util.Arrays#copyOf`
152149
*/
153150
def copyAs[A](original: Array[_], newLength: Int)(implicit ct: ClassTag[A]): Array[A] = {
154-
val destClass = ct.runtimeClass.asInstanceOf[Class[A]]
155-
if (destClass.isAssignableFrom(original.getClass.getComponentType)) {
156-
if(destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength)
157-
else {
158-
val destArrayClass = java.lang.reflect.Array.newInstance(destClass, 0).getClass.asInstanceOf[Class[Array[AnyRef]]]
159-
java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, destArrayClass).asInstanceOf[Array[A]]
151+
val runtimeClass = ct.runtimeClass
152+
if (runtimeClass == Void.TYPE) newUnitArray(newLength).asInstanceOf[Array[A]]
153+
else {
154+
val destClass = runtimeClass.asInstanceOf[Class[A]]
155+
if (destClass.isAssignableFrom(original.getClass.getComponentType)) {
156+
if (destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength)
157+
else {
158+
val destArrayClass = java.lang.reflect.Array.newInstance(destClass, 0).getClass.asInstanceOf[Class[Array[AnyRef]]]
159+
java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, destArrayClass).asInstanceOf[Array[A]]
160+
}
161+
} else {
162+
val dest = new Array[A](newLength)
163+
Array.copy(original, 0, dest, 0, original.length)
164+
dest
160165
}
161-
} else {
162-
val dest = new Array[A](newLength)
163-
Array.copy(original, 0, dest, 0, original.length)
164-
dest
165166
}
166167
}
167168

169+
private def newUnitArray(len: Int): Array[Unit] = {
170+
val result = new Array[Unit](len)
171+
java.util.Arrays.fill(result.asInstanceOf[Array[AnyRef]], ())
172+
result
173+
}
174+
168175
/** Returns an array of length 0 */
169176
def empty[T: ClassTag]: Array[T] = new Array[T](0)
170177

0 commit comments

Comments
 (0)