Skip to content

Commit c960179

Browse files
committed
Perform harmonization also in the presence of spread arguments
1 parent 54cea7b commit c960179

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import reporting.*
2525
import Nullables.*, NullOpsDecorator.*
2626
import config.{Feature, MigrationVersion, SourceVersion}
2727
import util.Property
28+
import util.chaining.tap
2829

2930
import collection.mutable
3031
import config.Printers.{overload, typr, unapp}
@@ -814,19 +815,17 @@ trait Applications extends Compatibility {
814815
addTyped(arg)
815816
case _ =>
816817
val elemFormal = formal.widenExpr.argTypesLo.head
817-
if Feature.enabled(Feature.multiSpreads)
818-
&& !ctx.isAfterTyper && args.exists(isVarArg)
819-
then
820-
args.foreach: arg =>
821-
if isVarArg(arg)
822-
then addArg(typedArg(arg, formal), formal)
823-
else addArg(typedArg(arg, elemFormal), elemFormal)
824-
else
825-
val typedArgs = harmonic(harmonizeArgs, elemFormal):
826-
args.map: arg =>
827-
checkNoVarArg(arg)
818+
val typedVarArgs = util.HashSet[TypedArg]()
819+
val typedArgs = harmonic(harmonizeArgs, elemFormal):
820+
args.map: arg =>
821+
if isVarArg(arg) then
822+
if !Feature.enabled(Feature.multiSpreads) || ctx.isAfterTyper then
823+
checkNoVarArg(arg)
824+
typedArg(arg, formal).tap(typedVarArgs += _)
825+
else
828826
typedArg(arg, elemFormal)
829-
typedArgs.foreach(addArg(_, elemFormal))
827+
typedArgs.foreach: targ =>
828+
addArg(targ, if typedVarArgs.contains(targ) then formal else elemFormal)
830829
makeVarArg(args.length, elemFormal)
831830
}
832831
else args match {
@@ -2704,7 +2703,8 @@ trait Applications extends Compatibility {
27042703
case ConstantType(c: Constant) if c.tag == IntTag =>
27052704
targetClass(ts1, cls, true)
27062705
case t =>
2707-
val sym = t.classSymbol
2706+
val sym =
2707+
if t.isRepeatedParam then t.argTypesLo.head.classSymbol else t.classSymbol
27082708
if (!sym.isNumericValueClass || cls.exists && cls != sym) NoSymbol
27092709
else targetClass(ts1, sym, intLitSeen)
27102710
}

tests/run/spreads.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ one
1010
one-two-three
1111
two
1212
ArraySeq(1, 1, 2, 3, 2)
13+
13.0

tests/run/spreads.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,13 @@ def useInt(xs: Int*) = ???
3535

3636
assert(sum(0, numbers1*, numbers2*, 4) == 25)
3737

38-
38+
// Tests for harmonization with varargs
39+
40+
val darr: Array[Double] = Array(1.0, 2)
41+
val zs1 = Array(1, darr*, 2, darr*, 3)
42+
val _: Array[Double] = zs1
43+
val d: Double = 4
44+
val zs2 = Array(1, darr*, 2, d, 3)
45+
val _: Array[Double] = zs2
46+
println(zs2.sum)
3947

0 commit comments

Comments
 (0)