Skip to content

Commit 0742026

Browse files
mboveltgodzik
authored andcommitted
Normalize tuple types when making seq literals for var args
1 parent c657425 commit 0742026

File tree

5 files changed

+19
-4
lines changed

5 files changed

+19
-4
lines changed

compiler/src/dotty/tools/dotc/core/TypeUtils.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ class TypeUtils:
115115
case Some(types) => TypeOps.nestedPairs(types)
116116
case None => throw new AssertionError("not a tuple")
117117

118+
/** If this is a generic tuple type with arity <= MaxTupleArity, return the
119+
* corresponding TupleN type, otherwise return this.
120+
*/
121+
def normalizedTupleType(using Context): Type =
122+
if self.isGenericTuple then
123+
self.tupleElementTypes match
124+
case Some(elems) if elems.size <= Definitions.MaxTupleArity => defn.tupleType(elems)
125+
case _ => self
126+
else
127+
self
118128
def refinedWith(name: Name, info: Type)(using Context) = RefinedType(self, name, info)
119129

120130
/** Is this type a methodic type that takes at least one parameter? */

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ trait Applications extends Compatibility {
841841
def makeVarArg(n: Int, elemFormal: Type): Unit = {
842842
val args = typedArgBuf.takeRight(n).toList
843843
typedArgBuf.dropRightInPlace(n)
844-
val elemtpt = TypeTree(elemFormal)
844+
val elemtpt = TypeTree(elemFormal.normalizedTupleType)
845845
typedArgBuf += seqToRepeated(SeqLiteral(args, elemtpt))
846846
}
847847

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
738738
// Otherwise, map combinations of A *: B *: .... EmptyTuple with nesting levels <= 22
739739
// to the Tuple class of the right arity and select from that one
740740
def trySmallGenericTuple(qual: Tree, withCast: Boolean) =
741-
if qual.tpe.isSmallGenericTuple then
741+
val tp = qual.tpe.widenTermRefExpr
742+
val tpNormalized = tp.normalizedTupleType
743+
if tp ne tpNormalized then
742744
if withCast then
743-
val elems = qual.tpe.widenTermRefExpr.tupleElementTypes.getOrElse(Nil)
744-
typedSelectWithAdapt(tree, pt, qual.cast(defn.tupleType(elems)))
745+
typedSelectWithAdapt(tree, pt, qual.cast(tpNormalized))
745746
else
746747
typedSelectWithAdapt(tree, pt, qual)
747748
else EmptyTree

tests/run/i22345.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@main def Test: Unit =
2+
val a: Array[(Int, String)] = Array[Int *: String *: EmptyTuple]()

tests/run/i22345b.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@main def Test: Unit =
2+
val a: Array[(Int, String)] = Array[Int *: String *: EmptyTuple]((1, "hello"))

0 commit comments

Comments
 (0)