@@ -158,35 +158,46 @@ class InlineReducer(inliner: Inliner)(using Context):
158158 *
159159 * where `def` is used for call-by-name parameters. However, we shortcut any NoPrefix
160160 * refs among the ei's directly without creating an intermediate binding.
161+ *
162+ * This variant of beta-reduction preserves the integrity of `Inlined` tree nodes.
161163 */
162164 def betaReduce (tree : Tree )(using Context ): Tree = tree match {
163- case Apply (Select (cl @ closureDef(ddef), nme.apply), args) if defn.isFunctionType(cl.tpe) =>
164- // closureDef also returns a result for closures wrapped in Inlined nodes.
165- // These need to be preserved.
166- def recur (cl : Tree ): Tree = cl match
167- case Inlined (call, bindings, expr) =>
168- cpy.Inlined (cl)(call, bindings, recur(expr))
169- case _ => ddef.tpe.widen match
170- case mt : MethodType if ddef.paramss.head.length == args.length =>
171- val bindingsBuf = new DefBuffer
172- val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
173- arg.tpe.dealias match {
174- case ref @ TermRef (NoPrefix , _) => ref.symbol
175- case _ =>
176- paramBindingDef(name, paramtp, arg, bindingsBuf)(
177- using ctx.withSource(cl.source)
178- ).symbol
165+ case Apply (Select (cl, nme.apply), args) if defn.isFunctionType(cl.tpe) =>
166+ val bindingsBuf = new DefBuffer
167+ def recur (cl : Tree ): Option [Tree ] = cl match
168+ case Inlined (call, bindings, expr) if bindings.forall(isPureBinding) =>
169+ recur(expr).map(cpy.Inlined (cl)(call, bindings, _))
170+ case Block (Nil , expr) =>
171+ recur(expr).map(cpy.Block (cl)(Nil , _))
172+ case Typed (expr, tpt) =>
173+ recur(expr).map(cpy.Typed (cl)(_, tpt))
174+ case Block ((ddef : DefDef ) :: Nil , closure : Closure ) if ddef.symbol == closure.meth.symbol =>
175+ ddef.tpe.widen match
176+ case mt : MethodType if ddef.paramss.head.length == args.length =>
177+ val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
178+ arg.tpe.dealias match {
179+ case ref @ TermRef (NoPrefix , _) => ref.symbol
180+ case _ =>
181+ paramBindingDef(name, paramtp, arg, bindingsBuf)(
182+ using ctx.withSource(cl.source)
183+ ).symbol
184+ }
179185 }
180- }
181- val expander = new TreeTypeMap (
182- oldOwners = ddef.symbol :: Nil ,
183- newOwners = ctx.owner :: Nil ,
184- substFrom = ddef.paramss.head.map(_.symbol),
185- substTo = argSyms)
186- Block (bindingsBuf.toList, expander.transform(ddef.rhs)).withSpan(tree.span)
187- case _ => tree
188- recur(cl)
189- case _ => tree
186+ val expander = new TreeTypeMap (
187+ oldOwners = ddef.symbol :: Nil ,
188+ newOwners = ctx.owner :: Nil ,
189+ substFrom = ddef.paramss.head.map(_.symbol),
190+ substTo = argSyms)
191+ Some (expander.transform(ddef.rhs))
192+ case _ => None
193+ case _ => None
194+ recur(cl) match
195+ case Some (reduced) =>
196+ Block (bindingsBuf.toList, reduced).withSpan(tree.span)
197+ case None =>
198+ tree
199+ case _ =>
200+ tree
190201 }
191202
192203 /** The result type of reducing a match. It consists optionally of a list of bindings
@@ -281,7 +292,7 @@ class InlineReducer(inliner: Inliner)(using Context):
281292 // Test case is pos-macros/i15971
282293 val tptBinds = getBinds(Set .empty[TypeSymbol ], tpt)
283294 val binds : Set [TypeSymbol ] = pat match {
284- case UnApply (TypeApply (_, tpts), _, _) =>
295+ case UnApply (TypeApply (_, tpts), _, _) =>
285296 getBinds(Set .empty[TypeSymbol ], tpts) ++ tptBinds
286297 case _ => tptBinds
287298 }
0 commit comments