@@ -723,11 +723,40 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
723
723
def inlinedFromOutside (tree : Tree )(span : Span ): Tree =
724
724
Inlined (EmptyTree , Nil , tree)(using ctx.withSource(inlinedMethod.topLevelClass.source)).withSpan(span)
725
725
726
+ // InlinerMap is a TreeTypeMap with special treatment for inlined arguments:
727
+ // They are generally left alone (not mapped further, and if they wrap a type
728
+ // the type Inlined wrapper gets dropped
729
+ class InlinerMap (
730
+ typeMap : Type => Type ,
731
+ treeMap : Tree => Tree ,
732
+ oldOwners : List [Symbol ],
733
+ newOwners : List [Symbol ],
734
+ substFrom : List [Symbol ],
735
+ substTo : List [Symbol ])(using Context )
736
+ extends TreeTypeMap (typeMap, treeMap, oldOwners, newOwners, substFrom, substTo):
737
+
738
+ override def copy (
739
+ typeMap : Type => Type ,
740
+ treeMap : Tree => Tree ,
741
+ oldOwners : List [Symbol ],
742
+ newOwners : List [Symbol ],
743
+ substFrom : List [Symbol ],
744
+ substTo : List [Symbol ])(using Context ) =
745
+ new InlinerMap (typeMap, treeMap, oldOwners, newOwners, substFrom, substTo)
746
+
747
+ override def transformInlined (tree : Inlined )(using Context ) =
748
+ if tree.call.isEmpty then
749
+ tree.expansion match
750
+ case expansion : TypeTree => expansion
751
+ case _ => tree
752
+ else super .transformInlined(tree)
753
+ end InlinerMap
754
+
726
755
// A tree type map to prepare the inlined body for typechecked.
727
756
// The translation maps references to `this` and parameters to
728
757
// corresponding arguments or proxies on the type and term level. It also changes
729
758
// the owner from the inlined method to the current owner.
730
- val inliner = new TreeTypeMap (
759
+ val inliner = new InlinerMap (
731
760
typeMap =
732
761
new DeepTypeMap {
733
762
def apply (t : Type ) = t match {
@@ -763,16 +792,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
763
792
val inlinedSingleton = singleton(t).withSpan(argSpan)
764
793
inlinedFromOutside(inlinedSingleton)(tree.span)
765
794
case Some (t) if tree.isType =>
766
- TypeTree (t).withSpan(argSpan)
795
+ inlinedFromOutside( TypeTree (t).withSpan(argSpan))(tree.span )
767
796
case _ => tree
768
797
}
769
798
case tree => tree
770
799
},
771
800
oldOwners = inlinedMethod :: Nil ,
772
- newOwners = ctx.owner :: Nil
773
- )( using inlineCtx) {
774
- override def stopAtInlinedArgument : Boolean = true
775
- }
801
+ newOwners = ctx.owner :: Nil ,
802
+ substFrom = Nil ,
803
+ substTo = Nil
804
+ )( using inlineCtx)
776
805
777
806
// Apply inliner to `rhsToInline`, split off any implicit bindings from result, and
778
807
// make them part of `bindingsBuf`. The expansion is then the tree that remains.
@@ -1012,26 +1041,31 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
1012
1041
*/
1013
1042
def betaReduce (tree : Tree )(using Context ): Tree = tree match {
1014
1043
case Apply (Select (cl @ closureDef(ddef), nme.apply), args) if defn.isFunctionType(cl.tpe) =>
1015
- ddef.tpe.widen match {
1016
- case mt : MethodType if ddef.paramss.head.length == args.length =>
1017
- val bindingsBuf = new mutable.ListBuffer [ValOrDefDef ]
1018
- val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
1019
- arg.tpe.dealias match {
1020
- case ref @ TermRef (NoPrefix , _) => ref.symbol
1021
- case _ =>
1022
- paramBindingDef(name, paramtp, arg, bindingsBuf)(
1023
- using ctx.withSource(cl.source)
1024
- ).symbol
1044
+ // closureDef also returns a result for closures wrapped in Inlined nodes.
1045
+ // These need to be preserved.
1046
+ def recur (cl : Tree ): Tree = cl match
1047
+ case Inlined (call, bindings, expr) =>
1048
+ cpy.Inlined (cl)(call, bindings, recur(expr))
1049
+ case _ => ddef.tpe.widen match
1050
+ case mt : MethodType if ddef.paramss.head.length == args.length =>
1051
+ val bindingsBuf = new mutable.ListBuffer [ValOrDefDef ]
1052
+ val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
1053
+ arg.tpe.dealias match {
1054
+ case ref @ TermRef (NoPrefix , _) => ref.symbol
1055
+ case _ =>
1056
+ paramBindingDef(name, paramtp, arg, bindingsBuf)(
1057
+ using ctx.withSource(cl.source)
1058
+ ).symbol
1059
+ }
1025
1060
}
1026
- }
1027
- val expander = new TreeTypeMap (
1028
- oldOwners = ddef.symbol :: Nil ,
1029
- newOwners = ctx.owner :: Nil ,
1030
- substFrom = ddef.paramss.head.map(_.symbol),
1031
- substTo = argSyms)
1032
- Block (bindingsBuf.toList, expander.transform(ddef.rhs))
1033
- case _ => tree
1034
- }
1061
+ val expander = new TreeTypeMap (
1062
+ oldOwners = ddef.symbol :: Nil ,
1063
+ newOwners = ctx.owner :: Nil ,
1064
+ substFrom = ddef.paramss.head.map(_.symbol),
1065
+ substTo = argSyms)
1066
+ Block (bindingsBuf.toList, expander.transform(ddef.rhs)).withSpan(tree.span)
1067
+ case _ => tree
1068
+ recur(cl)
1035
1069
case _ => tree
1036
1070
}
1037
1071
0 commit comments