@@ -24,6 +24,7 @@ import Inferencing.*
24
24
import reporting .*
25
25
import Nullables .* , NullOpsDecorator .*
26
26
import config .{Feature , MigrationVersion , SourceVersion }
27
+ import util .Property
27
28
28
29
import collection .mutable
29
30
import config .Printers .{overload , typr , unapp }
@@ -42,6 +43,17 @@ import dotty.tools.dotc.inlines.Inlines
42
43
object Applications {
43
44
import tpd .*
44
45
46
+ /** Attachment key for SeqLiterals containing spreads. Eliminated at PostTyper */
47
+ val HasSpreads = new Property .StickyKey [Unit ]
48
+
49
+ /** An extractor for spreads in sequence literals */
50
+ object spread :
51
+ def apply (arg : Tree , elemtpt : Tree )(using Context ) =
52
+ ref(defn.spreadMethod).appliedToTypeTree(elemtpt).appliedTo(arg)
53
+ def unapply (arg : Apply )(using Context ): Option [Tree ] = arg match
54
+ case Apply (fn, x :: Nil ) if fn.symbol == defn.spreadMethod => Some (x)
55
+ case _ => None
56
+
45
57
def extractorMember (tp : Type , name : Name )(using Context ): SingleDenotation =
46
58
tp.member(name).suchThat(sym => sym.info.isParameterless && sym.info.widenExpr.isValueType)
47
59
@@ -797,14 +809,19 @@ trait Applications extends Compatibility {
797
809
addTyped(arg)
798
810
case _ =>
799
811
val elemFormal = formal.widenExpr.argTypesLo.head
800
- val typedArgs =
801
- harmonic(harmonizeArgs, elemFormal) {
802
- args.map { arg =>
812
+ if Feature .enabled(Feature .multiSpreads)
813
+ && ! ctx.isAfterTyper && args.exists(isVarArg)
814
+ then
815
+ args.foreach: arg =>
816
+ if isVarArg(arg)
817
+ then addArg(typedArg(arg, formal), formal)
818
+ else addArg(typedArg(arg, elemFormal), elemFormal)
819
+ else
820
+ val typedArgs = harmonic(harmonizeArgs, elemFormal):
821
+ args.map: arg =>
803
822
checkNoVarArg(arg)
804
823
typedArg(arg, elemFormal)
805
- }
806
- }
807
- typedArgs.foreach(addArg(_, elemFormal))
824
+ typedArgs.foreach(addArg(_, elemFormal))
808
825
makeVarArg(args.length, elemFormal)
809
826
}
810
827
else args match {
@@ -944,12 +961,18 @@ trait Applications extends Compatibility {
944
961
typedArgBuf += typedArg
945
962
ok = ok & ! typedArg.tpe.isError
946
963
947
- def makeVarArg (n : Int , elemFormal : Type ): Unit = {
948
- val args = typedArgBuf.takeRight(n).toList
964
+ def makeVarArg (n : Int , elemFormal : Type ): Unit =
965
+ var args = typedArgBuf.takeRight(n).toList
949
966
typedArgBuf.dropRightInPlace(n)
950
- val elemtpt = TypeTree (elemFormal.normalizedTupleType, inferred = true )
951
- typedArgBuf += seqToRepeated(SeqLiteral (args, elemtpt))
952
- }
967
+ val elemTpe = elemFormal.normalizedTupleType
968
+ val elemtpt = TypeTree (elemTpe, inferred = true )
969
+ def wrapSpread (arg : Tree ): Tree = arg match
970
+ case Typed (argExpr, tpt) if tpt.tpe.isRepeatedParam => spread(argExpr, elemtpt)
971
+ case _ => arg
972
+ val args1 = args.mapConserve(wrapSpread)
973
+ val seqLit = SeqLiteral (args1, elemtpt)
974
+ if args1 ne args then seqLit.putAttachment(HasSpreads , ())
975
+ typedArgBuf += seqToRepeated(seqLit)
953
976
954
977
def harmonizeArgs (args : List [TypedArg ]): List [Tree ] =
955
978
// harmonize args only if resType depends on parameter types
0 commit comments