@@ -454,6 +454,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
454
454
override val cpy : TypedTreeCopier = // Type ascription needed to pick up any new members in TreeCopier (currently there are none)
455
455
new TypedTreeCopier
456
456
457
+ val cpyBetweenPhases = new TimeTravellingTreeCopier
458
+
457
459
class TypedTreeCopier extends TreeCopier {
458
460
def postProcess (tree : Tree , copied : untpd.Tree ): copied.ThisTree [Type ] =
459
461
copied.withTypeUnchecked(tree.tpe)
@@ -473,26 +475,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
473
475
}
474
476
475
477
override def Apply (tree : Tree )(fun : Tree , args : List [Tree ])(implicit ctx : Context ): Apply = {
476
- val untyped = untpd.cpy.Apply (tree)(fun, args)
477
- if (untyped.ne(tree) || ! ctx.settings.optimise.value)
478
- ta.assignType(untyped, fun, args)
479
- else
480
- tree.asInstanceOf [Apply ]
478
+ val tree1 = untpd.cpy.Apply (tree)(fun, args)
479
+ tree match {
480
+ case tree : Apply
481
+ if (fun.tpe eq tree.fun.tpe) && (args corresponds tree.args)(_ eq _) =>
482
+ tree1.withTypeUnchecked(tree.tpe)
483
+ case _ => ta.assignType(tree1, fun, args)
484
+ }
481
485
}
482
486
483
- // Note: Reassigning the original type if `fun` and `args` have the same types as before
484
- // does not work here: The computed type depends on the widened function type, not
485
- // the function type itself. A treetransform may keep the function type the
486
- // same but its widened type might change.
487
-
488
487
override def TypeApply (tree : Tree )(fun : Tree , args : List [Tree ])(implicit ctx : Context ): TypeApply = {
489
- val untyped = untpd.cpy.TypeApply (tree)(fun, args)
490
- if (untyped.ne(tree) || ! ctx.settings.optimise.value)
491
- ta.assignType(untyped, fun, args)
492
- else
493
- tree.asInstanceOf [TypeApply ]
488
+ val tree1 = untpd.cpy.TypeApply (tree)(fun, args)
489
+ tree match {
490
+ case tree : TypeApply
491
+ if (fun.tpe eq tree.fun.tpe) && (args corresponds tree.args)(_ eq _) =>
492
+ tree1.withTypeUnchecked(tree.tpe)
493
+ case _ => ta.assignType(tree1, fun, args)
494
+ }
494
495
}
495
- // Same remark as for Apply
496
496
497
497
override def Literal (tree : Tree )(const : Constant )(implicit ctx : Context ): Literal =
498
498
ta.assignType(untpd.cpy.Literal (tree)(const))
@@ -525,14 +525,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
525
525
}
526
526
}
527
527
528
- override def Closure (tree : Tree )(env : List [Tree ], meth : Tree , tpt : Tree )(implicit ctx : Context ): Closure = {
529
- val untyped = untpd.cpy.Closure (tree)(env, meth, tpt)
530
- val typed = ta.assignType(untyped, meth, tpt)
531
- if (untyped.ne(tree) || ! ctx.settings.optimise.value)
532
- typed
533
- else
534
- tree.asInstanceOf [Closure ]
535
- }
528
+ override def Closure (tree : Tree )(env : List [Tree ], meth : Tree , tpt : Tree )(implicit ctx : Context ): Closure =
529
+ ta.assignType(untpd.cpy.Closure (tree)(env, meth, tpt), meth, tpt)
536
530
// Same remark as for Apply
537
531
538
532
override def Match (tree : Tree )(selector : Tree , cases : List [CaseDef ])(implicit ctx : Context ): Match = {
@@ -591,6 +585,19 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
591
585
Try (tree : Tree )(expr, cases, finalizer)
592
586
}
593
587
588
+ class TimeTravellingTreeCopier extends TypedTreeCopier {
589
+ override def Apply (tree : Tree )(fun : Tree , args : List [Tree ])(implicit ctx : Context ): Apply =
590
+ ta.assignType(untpd.cpy.Apply (tree)(fun, args), fun, args)
591
+ // Note: Reassigning the original type if `fun` and `args` have the same types as before
592
+ // does not work here: The computed type depends on the widened function type, not
593
+ // the function type itself. A treetransform may keep the function type the
594
+ // same but its widened type might change.
595
+
596
+ override def TypeApply (tree : Tree )(fun : Tree , args : List [Tree ])(implicit ctx : Context ): TypeApply =
597
+ ta.assignType(untpd.cpy.TypeApply (tree)(fun, args), fun, args)
598
+ // Same remark as for Apply
599
+ }
600
+
594
601
override def skipTransform (tree : Tree )(implicit ctx : Context ) = tree.tpe.isError
595
602
596
603
implicit class TreeOps [ThisTree <: tpd.Tree ](val tree : ThisTree ) extends AnyVal {
@@ -967,3 +974,4 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
967
974
if (file != null && file.exists) new SourceFile (file, Codec (encoding)) else NoSource
968
975
}
969
976
}
977
+
0 commit comments