@@ -24,13 +24,17 @@ import NameKinds.DefaultGetterName
24
24
import ProtoTypes ._
25
25
import EtaExpansion ._
26
26
import Inferencing ._
27
+
27
28
import collection .mutable
28
29
import config .Printers .{typr , unapp , overload }
29
30
import TypeApplications ._
31
+
30
32
import language .implicitConversions
31
33
import reporting .diagnostic .Message
32
34
import Constants .{Constant , IntTag , LongTag }
33
35
36
+ import scala .collection .mutable .ListBuffer
37
+
34
38
object Applications {
35
39
import tpd ._
36
40
@@ -580,20 +584,17 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
580
584
myNormalizedFun = liftApp(liftedDefs, myNormalizedFun)
581
585
}
582
586
583
- /** The index of the first difference between lists of trees `xs` and `ys`,
584
- * where `EmptyTree`s in the second list are skipped.
587
+ /** The index of the first difference between lists of trees `xs` and `ys`
585
588
* -1 if there are no differences.
586
589
*/
587
590
private def firstDiff [T <: Trees .Tree [_]](xs : List [T ], ys : List [T ], n : Int = 0 ): Int = xs match {
588
591
case x :: xs1 =>
589
592
ys match {
590
- case EmptyTree :: ys1 => firstDiff(xs1, ys1, n)
591
593
case y :: ys1 => if (x ne y) n else firstDiff(xs1, ys1, n + 1 )
592
594
case nil => n
593
595
}
594
596
case nil =>
595
597
ys match {
596
- case EmptyTree :: ys1 => firstDiff(xs, ys1, n)
597
598
case y :: ys1 => n
598
599
case nil => - 1
599
600
}
@@ -606,13 +607,33 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
606
607
val app1 =
607
608
if (! success) app0.withType(UnspecifiedErrorType )
608
609
else {
609
- if (! sameSeq(args, orderedArgs) && ! isJavaAnnotConstr(methRef.symbol)) {
610
+ if (! sameSeq(args, orderedArgs.dropWhile(_ eq EmptyTree ) ) && ! isJavaAnnotConstr(methRef.symbol)) {
610
611
// need to lift arguments to maintain evaluation order in the
611
612
// presence of argument reorderings.
613
+
612
614
liftFun()
613
- val eqSuffixLength = firstDiff(app.args.reverse, orderedArgs.reverse)
614
- val (liftable, rest) = typedArgs splitAt (typedArgs.length - eqSuffixLength)
615
- typedArgs = liftArgs(liftedDefs, methType, liftable) ++ rest
615
+
616
+ // lift arguments in the definition order
617
+ val argDefBuf = mutable.ListBuffer .empty[Tree ]
618
+ typedArgs = liftArgs(argDefBuf, methType, typedArgs)
619
+
620
+ // Lifted arguments ordered based on the original order of typedArgBuf and
621
+ // with all non-explicit default parameters at the end in declaration order.
622
+ val orderedArgDefs = {
623
+ // List of original arguments that are lifted by liftArgs
624
+ val impureArgs = typedArgBuf.filterNot(isPureExpr)
625
+ // Assuming stable sorting all non-explicit default parameters will remain in the end with the same order
626
+ val defaultParamIndex = args.size
627
+ // Mapping of index of each `liftable` into original args ordering
628
+ val indices = impureArgs.map { arg =>
629
+ val idx = args.indexOf(arg)
630
+ if (idx >= 0 ) idx // original index skipping pure arguments
631
+ else defaultParamIndex
632
+ }
633
+ scala.util.Sorting .stableSort[(Tree , Int ), Int ](argDefBuf zip indices, x => x._2).map(_._1)
634
+ }
635
+
636
+ liftedDefs ++= orderedArgDefs
616
637
}
617
638
if (sameSeq(typedArgs, args)) // trick to cut down on tree copying
618
639
typedArgs = args.asInstanceOf [List [Tree ]]
0 commit comments