diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index f5ce7a6b4698..83fca3908836 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -386,6 +386,12 @@ object TypeErasure { case _ => false } + /** Is `tp` of the form `Array^N[T]` where T is generic? */ + def isGenericArrayArg(tp: Type)(using Context): Boolean = tp.dealias match + case defn.ArrayOf(elem) => isGenericArrayArg(elem) + case _ => isGeneric(tp) + end isGenericArrayArg + /** The erased least upper bound of two erased types is computed as follows * - if both argument are arrays of objects, an array of the erased lub of the element types * - if both arguments are arrays of same primitives, an array of this primitive diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 38d5bcf3fe9b..90cc7c9a3d84 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -1282,14 +1282,11 @@ trait Applications extends Compatibility { def convertNewGenericArray(tree: Tree)(using Context): Tree = tree match { case Apply(TypeApply(tycon, targs@(targ :: Nil)), args) if tycon.symbol == defn.ArrayConstructor => fullyDefinedType(tree.tpe, "array", tree.srcPos) - - def newGenericArrayCall = + if TypeErasure.isGenericArrayArg(targ.tpe) then ref(defn.DottyArraysModule) - .select(defn.newGenericArrayMethod).withSpan(tree.span) - .appliedToTypeTrees(targs).appliedToTermArgs(args) - - if (TypeErasure.isGeneric(targ.tpe)) - newGenericArrayCall + .select(defn.newGenericArrayMethod).withSpan(tree.span) + .appliedToTypeTrees(targs) + .appliedToTermArgs(args) else tree case _ => tree diff --git a/tests/run/i23901.scala b/tests/run/i23901.scala new file mode 100644 index 000000000000..7bfcfff23551 --- /dev/null +++ b/tests/run/i23901.scala @@ -0,0 +1,8 @@ +import scala.reflect.ClassTag + +object MyArray: + def empty[T: ClassTag]: Array[Array[T]] = new Array[Array[T]](0) + +@main def Test = + val arr: Array[Array[String]] = MyArray.empty[String] + assert(arr.length == 0)