@@ -454,6 +454,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
454454 override val cpy : TypedTreeCopier = // Type ascription needed to pick up any new members in TreeCopier (currently there are none)
455455 new TypedTreeCopier
456456
457+ val cpyBetweenPhases = new TimeTravellingTreeCopier
458+
457459 class TypedTreeCopier extends TreeCopier {
458460 def postProcess (tree : Tree , copied : untpd.Tree ): copied.ThisTree [Type ] =
459461 copied.withTypeUnchecked(tree.tpe)
@@ -473,26 +475,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
473475 }
474476
475477 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+ }
481485 }
482486
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-
488487 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+ }
494495 }
495- // Same remark as for Apply
496496
497497 override def Literal (tree : Tree )(const : Constant )(implicit ctx : Context ): Literal =
498498 ta.assignType(untpd.cpy.Literal (tree)(const))
@@ -525,14 +525,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
525525 }
526526 }
527527
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)
536530 // Same remark as for Apply
537531
538532 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 {
591585 Try (tree : Tree )(expr, cases, finalizer)
592586 }
593587
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+
594601 override def skipTransform (tree : Tree )(implicit ctx : Context ) = tree.tpe.isError
595602
596603 implicit class TreeOps [ThisTree <: tpd.Tree ](val tree : ThisTree ) extends AnyVal {
@@ -967,3 +974,4 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
967974 if (file != null && file.exists) new SourceFile (file, Codec (encoding)) else NoSource
968975 }
969976}
977+
0 commit comments