Skip to content

Commit

Permalink
Fix #22226: Use classOf[BoxedUnit] for Unit array in `ArrayConstruc…
Browse files Browse the repository at this point in the history
…tors`. (#22238)

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.
  • Loading branch information
hamzaremmal authored Dec 18, 2024
2 parents 60b5dd1 + 442e6a0 commit bd1f004
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ class ArrayConstructors extends MiniPhase {

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

if (tree.fun.symbol eq defn.ArrayConstructor) {
val TypeApply(tycon, targ :: Nil) = tree.fun: @unchecked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ class RegressionTestScala3 {
assertEquals(5, Issue14289.Container.b())
assertEquals(true, Issue14289.Container.c())
}

@Test def createArrayOfUnitIssue22226(): Unit = {
val a = Array.ofDim[Unit](0)
assertSame(classOf[Array[Unit]], a.getClass())

val b = new Array[Unit](0)
assertSame(classOf[Array[Unit]], b.getClass())

val c = Array.ofDim[Unit](0, 0)
assertSame(classOf[Array[Array[Unit]]], c.getClass())
}
}

object RegressionTestScala3 {
Expand Down

0 comments on commit bd1f004

Please sign in to comment.