@@ -158,35 +158,46 @@ class InlineReducer(inliner: Inliner)(using Context):
158
158
*
159
159
* where `def` is used for call-by-name parameters. However, we shortcut any NoPrefix
160
160
* 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.
161
163
*/
162
164
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)
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
+ }
179
185
}
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
190
201
}
191
202
192
203
/** 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):
281
292
// Test case is pos-macros/i15971
282
293
val tptBinds = getBinds(Set .empty[TypeSymbol ], tpt)
283
294
val binds : Set [TypeSymbol ] = pat match {
284
- case UnApply (TypeApply (_, tpts), _, _) =>
295
+ case UnApply (TypeApply (_, tpts), _, _) =>
285
296
getBinds(Set .empty[TypeSymbol ], tpts) ++ tptBinds
286
297
case _ => tptBinds
287
298
}
0 commit comments