@@ -3,7 +3,7 @@ package dotc
3
3
package typer
4
4
5
5
import core ._
6
- import ast .{TreeInfo , Trees , tpd , untpd }
6
+ import ast .{Trees , untpd , tpd , TreeInfo }
7
7
import util .Positions ._
8
8
import util .Stats .track
9
9
import Trees .Untyped
@@ -26,7 +26,7 @@ import EtaExpansion._
26
26
import Inferencing ._
27
27
28
28
import collection .mutable
29
- import config .Printers .{overload , typr , unapp }
29
+ import config .Printers .{typr , unapp , overload }
30
30
import TypeApplications ._
31
31
32
32
import language .implicitConversions
@@ -583,25 +583,6 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
583
583
myNormalizedFun = liftApp(liftedDefs, myNormalizedFun)
584
584
}
585
585
586
- /** The index of the first difference between lists of trees `xs` and `ys`,
587
- * where initial `EmptyTree`s in the second list are skipped.
588
- * -1 if there are no differences.
589
- */
590
- private def firstDiffSkipInitEmptyTrees [T <: Trees .Tree [_]](xs : List [T ], ys : List [T ], n : Int = 0 ): Int = xs match {
591
- case x :: xs1 =>
592
- ys match {
593
- case EmptyTree :: ys1 => firstDiffSkipInitEmptyTrees(xs, ys1, n)
594
- case y :: ys1 => if (x ne y) n else firstDiff(xs1, ys1, n + 1 )
595
- case nil => n
596
- }
597
- case nil =>
598
- ys match {
599
- case EmptyTree :: ys1 => firstDiffSkipInitEmptyTrees(xs, ys1, n)
600
- case y :: ys1 => n
601
- case nil => - 1
602
- }
603
- }
604
-
605
586
/** The index of the first difference between lists of trees `xs` and `ys`
606
587
* -1 if there are no differences.
607
588
*/
@@ -617,45 +598,42 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
617
598
case nil => - 1
618
599
}
619
600
}
601
+ private def sameSeq [T <: Trees .Tree [_]](xs : List [T ], ys : List [T ]): Boolean = firstDiff(xs, ys) < 0
620
602
621
603
val result = {
622
604
var typedArgs = typedArgBuf.toList
623
605
def app0 = cpy.Apply (app)(normalizedFun, typedArgs) // needs to be a `def` because typedArgs can change later
624
606
val app1 =
625
607
if (! success) app0.withType(UnspecifiedErrorType )
626
608
else {
627
- if (firstDiffSkipInitEmptyTrees (args, orderedArgs) >= 0 && ! isJavaAnnotConstr(methRef.symbol)) {
609
+ if (sameSeq (args, orderedArgs.dropWhile(_ eq EmptyTree )) && ! isJavaAnnotConstr(methRef.symbol)) {
628
610
// need to lift arguments to maintain evaluation order in the
629
611
// presence of argument reorderings.
612
+
630
613
liftFun()
631
- val eqSuffixLength = firstDiffSkipInitEmptyTrees(app.args.reverse, orderedArgs.reverse)
632
- val (liftable, rest) = typedArgs splitAt (typedArgs.length - eqSuffixLength)
633
-
634
- // Mapping of index of each `liftable` into original args ordering
635
- var indices = ListBuffer .empty[Int ]
636
- var nextDefaultParamIndex = args.size
637
- var prefixShift = 0
638
- if (liftedDefs.nonEmpty) {
639
- indices += 0
640
- prefixShift = 1
641
- }
642
- liftable.foreach {
643
- case NamedArg (_, arg) if isPureExpr(arg) =>
644
- case arg if isPureExpr(arg) =>
645
- case arg =>
646
- if (args.contains(arg)) {
647
- indices += prefixShift + args.indexOf(arg)
648
- } else {
649
- indices += prefixShift + nextDefaultParamIndex
650
- nextDefaultParamIndex += 1
651
- }
652
- }
653
614
654
- typedArgs = liftArgs(liftedDefs, methType, liftable) ++ rest
615
+ // lift arguments in the definition order
616
+ val argDefBuff = mutable.ListBuffer .empty[Tree ]
617
+ typedArgs = liftArgs(argDefBuff, methType, typedArgs)
618
+
619
+ def orderedArgDefs = {
620
+ val impureArgs = typedArgBuf.filterNot { // pure are not lifted by liftArgs
621
+ case NamedArg (_, arg) => isPureExpr(arg)
622
+ case arg => isPureExpr(arg)
623
+ }
624
+ var defaultParamIndex = args.size
625
+ // Mapping of index of each `liftable` into original args ordering
626
+ val indices = impureArgs.map { arg =>
627
+ val idx = args.indexOf(arg)
628
+ if (idx >= 0 ) args.indexOf(arg)
629
+ else defaultParamIndex // assuming stable sorting
630
+ }
631
+ scala.util.Sorting .stableSort[(Tree , Int ), Int ](argDefBuff zip indices, x => x._2).map(_._1)
632
+ }
655
633
656
- liftedDefs = (liftedDefs zip indices).sortBy(_._2).unzip._1.to
634
+ liftedDefs ++= orderedArgDefs
657
635
}
658
- if (firstDiff (typedArgs, args) < 0 ) // trick to cut down on tree copying
636
+ if (sameSeq (typedArgs, args)) // trick to cut down on tree copying
659
637
typedArgs = args.asInstanceOf [List [Tree ]]
660
638
assignType(app0, normalizedFun, typedArgs)
661
639
}
0 commit comments