Skip to content

Commit 8ab9133

Browse files
committed
Don't drop Inlined nodes in beta reduce
Partial fix for #11894
1 parent 6c82605 commit 8ab9133

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -995,26 +995,31 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
995995
*/
996996
def betaReduce(tree: Tree)(using Context): Tree = tree match {
997997
case Apply(Select(cl @ closureDef(ddef), nme.apply), args) if defn.isFunctionType(cl.tpe) =>
998-
ddef.tpe.widen match {
999-
case mt: MethodType if ddef.paramss.head.length == args.length =>
1000-
val bindingsBuf = new mutable.ListBuffer[ValOrDefDef]
1001-
val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
1002-
arg.tpe.dealias match {
1003-
case ref @ TermRef(NoPrefix, _) => ref.symbol
1004-
case _ =>
1005-
paramBindingDef(name, paramtp, arg, bindingsBuf)(
1006-
using ctx.withSource(cl.source)
1007-
).symbol
998+
// closureDef also returns a result for closures wrapped in Inlined nodes.
999+
// These need to be preserved.
1000+
def recur(cl: Tree): Tree = cl match
1001+
case Inlined(call, bindings, expr) =>
1002+
cpy.Inlined(cl)(call, bindings, recur(expr))
1003+
case _ => ddef.tpe.widen match
1004+
case mt: MethodType if ddef.paramss.head.length == args.length =>
1005+
val bindingsBuf = new mutable.ListBuffer[ValOrDefDef]
1006+
val argSyms = mt.paramNames.lazyZip(mt.paramInfos).lazyZip(args).map { (name, paramtp, arg) =>
1007+
arg.tpe.dealias match {
1008+
case ref @ TermRef(NoPrefix, _) => ref.symbol
1009+
case _ =>
1010+
paramBindingDef(name, paramtp, arg, bindingsBuf)(
1011+
using ctx.withSource(cl.source)
1012+
).symbol
1013+
}
10081014
}
1009-
}
1010-
val expander = new TreeTypeMap(
1011-
oldOwners = ddef.symbol :: Nil,
1012-
newOwners = ctx.owner :: Nil,
1013-
substFrom = ddef.paramss.head.map(_.symbol),
1014-
substTo = argSyms)
1015-
Block(bindingsBuf.toList, expander.transform(ddef.rhs))
1016-
case _ => tree
1017-
}
1015+
val expander = new TreeTypeMap(
1016+
oldOwners = ddef.symbol :: Nil,
1017+
newOwners = ctx.owner :: Nil,
1018+
substFrom = ddef.paramss.head.map(_.symbol),
1019+
substTo = argSyms)
1020+
Block(bindingsBuf.toList, expander.transform(ddef.rhs)).withSpan(tree.span)
1021+
case _ => tree
1022+
recur(cl)
10181023
case _ => tree
10191024
}
10201025

tests/pos/i11894a.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
object CallbackTo {
2+
extension [A](self: CallbackTo[Option[A]]) {
3+
transparent inline def asOption: Option[A] =
4+
self.toScalaFn()
5+
}
6+
}
7+
8+
final class CallbackTo[A] (val x: List[A]) {
9+
10+
transparent inline def runNow(): A =
11+
x.head
12+
13+
transparent inline def toScalaFn: () => A =
14+
() => runNow()
15+
16+
def map[B](f: A => B): CallbackTo[B] =
17+
???
18+
19+
def toOption: Option[A] = {
20+
val x = map[Option[A]](Some(_))
21+
val y = x: CallbackTo[Option[A]] // ok: type is what we expect
22+
y.asOption // error
23+
}
24+
}

0 commit comments

Comments
 (0)