Skip to content

Commit c612ddb

Browse files
sjrdtgodzik
authored andcommitted
Fix scala#22226: Use classOf[BoxedUnit] for Unit array in ArrayConstructors.
The `ArrayConstructors` phase rewrites array constructors to calls to `scala.runtime.Arrays.newArray`. When it does that, it must pass the run-time `jl.Class` of the element type. Previously, it used `classOf[Unit]` when creating an `Array[Unit]` (or nested). That is not correct, as from the Java perspective, we need to create `Array[BoxedUnit]`. We now identify `elemType <: Unit` and replace it with `BoxedUnit`. --- This highlights a limitation of the Scala.js backend. We should rewrite calls to `newArray` in the backend to use direct array creation instead. [Cherry-picked 442e6a0]
1 parent 95dcbc6 commit c612ddb

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ class ArrayConstructors extends MiniPhase {
2727

2828
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree = {
2929
def expand(elemType: Type, dims: List[Tree]) =
30-
tpd.newArray(elemType, tree.tpe, tree.span, JavaSeqLiteral(dims, TypeTree(defn.IntClass.typeRef)))
30+
val elemTypeNonVoid =
31+
if elemType.isValueSubType(defn.UnitType) then defn.BoxedUnitClass.typeRef
32+
else elemType
33+
tpd.newArray(elemTypeNonVoid, tree.tpe, tree.span, JavaSeqLiteral(dims, TypeTree(defn.IntClass.typeRef)))
3134

3235
if (tree.fun.symbol eq defn.ArrayConstructor) {
3336
val TypeApply(tycon, targ :: Nil) = tree.fun: @unchecked

Diff for: tests/sjs-junit/test/org/scalajs/testsuite/compiler/RegressionTestScala3.scala

+11
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ class RegressionTestScala3 {
145145
assertEquals(5, Issue14289.Container.b())
146146
assertEquals(true, Issue14289.Container.c())
147147
}
148+
149+
@Test def createArrayOfUnitIssue22226(): Unit = {
150+
val a = Array.ofDim[Unit](0)
151+
assertSame(classOf[Array[Unit]], a.getClass())
152+
153+
val b = new Array[Unit](0)
154+
assertSame(classOf[Array[Unit]], b.getClass())
155+
156+
val c = Array.ofDim[Unit](0, 0)
157+
assertSame(classOf[Array[Array[Unit]]], c.getClass())
158+
}
148159
}
149160

150161
object RegressionTestScala3 {

0 commit comments

Comments
 (0)