Skip to content

Commit 477dfe1

Browse files
committed
Ensure type correctness of repeated arguments
Make sure elimRepeated produces array arguments that match the formal parameter type. Previously, there was a gap which showed itself when compiling scala/concurrent/forkjoin/package.scala There, the method expected a repeated argument of type ForkJoinTask[_], so the expected type was Array[ForkJoinTask[_]]. But the type computed by seqToArray was Array[ForkJoinTask[T]]. Since arrays are non-variant, these types are not compatible! This somehow slipped through with the previous implementation of applied types.
1 parent 35b484a commit 477dfe1

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Flags._
1111
import Contexts.Context
1212
import Symbols._
1313
import Constants._
14+
import Decorators._
1415
import Denotations._, SymDenotations._
1516
import Decorators.StringInterpolators
1617
import dotty.tools.dotc.ast.tpd
@@ -73,18 +74,23 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
7374
transformTypeOfTree(tree)
7475

7576
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
76-
val args1 = tree.args.map {
77-
case arg: Typed if isWildcardStarArg(arg) =>
78-
if (tree.fun.symbol.is(JavaDefined) && arg.expr.tpe.derivesFrom(defn.SeqClass))
79-
seqToArray(arg.expr)
80-
else arg.expr
81-
case arg => arg
77+
val formals = (tree.fun.tpe.widen: @unchecked) match {
78+
case mt: MethodType => mt.paramInfos
79+
}
80+
val args1 = tree.args.zipWithConserve(formals) { (arg, formal) =>
81+
arg match {
82+
case arg: Typed if isWildcardStarArg(arg) =>
83+
if (tree.fun.symbol.is(JavaDefined) && arg.expr.tpe.derivesFrom(defn.SeqClass))
84+
seqToArray(arg.expr, formal.translateParameterized(defn.RepeatedParamClass, defn.ArrayClass))
85+
else arg.expr
86+
case arg => arg
87+
}
8288
}
8389
transformTypeOfTree(cpy.Apply(tree)(tree.fun, args1))
8490
}
8591

86-
/** Convert sequence argument to Java array */
87-
private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match {
92+
/** Convert sequence argument to Java array of type `pt` */
93+
private def seqToArray(tree: Tree, pt: Type)(implicit ctx: Context): Tree = tree match {
8894
case SeqLiteral(elems, elemtpt) =>
8995
JavaSeqLiteral(elems, elemtpt)
9096
case _ =>
@@ -95,7 +101,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
95101
.select(nme.seqToArray)
96102
.appliedToType(elemType)
97103
.appliedTo(tree, Literal(Constant(elemClass.typeRef)))
98-
.ensureConforms(defn.ArrayOf(elemType))
104+
.ensureConforms(pt)
99105
// Because of phantomclasses, the Java array's type might not conform to the return type
100106
}
101107

0 commit comments

Comments
 (0)