Skip to content

Commit 25304a0

Browse files
committed
Add initializers for lambdalift proxy fields
If an inner class has proxy fields, we missed so far the assignment sfrom the proxy parameters in the primary constructor of the class to the proxy fields. Test case tries several variations of this.
1 parent bbc584f commit 25304a0

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
7676
def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block =
7777
ta.assignType(untpd.Block(stats, expr), stats, expr)
7878

79-
def maybeBlock(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
80-
if (stats.isEmpty) expr else Block(stats, expr)
79+
/** Join `stats` in front of `expr` creating a new block if necessary */
80+
def seq(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
81+
if (stats.isEmpty) expr
82+
else expr match {
83+
case Block(estats, eexpr) => cpy.Block(expr)(stats ::: estats, eexpr)
84+
case _ => Block(stats, expr)
85+
}
8186

8287
def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
8388
ta.assignType(untpd.If(cond, thenp, elsep), thenp, elsep)

src/dotty/tools/dotc/transform/LambdaLift.scala

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,14 +384,23 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
384384
private def addFreeParams(tree: Tree, proxies: List[Symbol])(implicit ctx: Context, info: TransformerInfo): Tree = proxies match {
385385
case Nil => tree
386386
case proxies =>
387+
val sym = tree.symbol
387388
val ownProxies =
388-
if (!tree.symbol.isConstructor) proxies
389-
else proxies.map(_.copy(owner = tree.symbol, flags = Synthetic | Param))
389+
if (!sym.isConstructor) proxies
390+
else proxies.map(_.copy(owner = sym, flags = Synthetic | Param))
390391
val freeParamDefs = ownProxies.map(proxy =>
391392
transformFollowingDeep(ValDef(proxy.asTerm).withPos(tree.pos)).asInstanceOf[ValDef])
393+
def proxyInit(field: Symbol, param: Symbol) =
394+
transformFollowingDeep(ref(field).becomes(ref(param)))
395+
def copyParams(rhs: Tree) = {
396+
ctx.log(i"copy params ${proxies.map(_.showLocated)}%, %, own = ${ownProxies.map(_.showLocated)}%, %")
397+
seq((proxies, ownProxies).zipped.map(proxyInit), rhs)
398+
}
392399
tree match {
393400
case tree: DefDef =>
394-
cpy.DefDef(tree)(vparamss = tree.vparamss.map(freeParamDefs ++ _))
401+
cpy.DefDef(tree)(
402+
vparamss = tree.vparamss.map(freeParamDefs ++ _),
403+
rhs = if (sym.isPrimaryConstructor) copyParams(tree.rhs) else tree.rhs)
395404
case tree: Template =>
396405
cpy.Template(tree)(body = freeParamDefs ++ tree.body)
397406
}

tests/run/i659.scala

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
class Foo(val a: Int) {
2-
//def foo = { {case x => x + a}: PartialFunction[Int, Int]}
2+
def foo = { {case x => x + a}: PartialFunction[Int, Int]}
33
class Bar { def result(x: Int) = x + a }
44
def bar = new Bar
55
}
66

7+
class VFoo(val a: Int) extends AnyVal {
8+
def foo = { {case x => x + a}: PartialFunction[Int, Int]}
9+
}
10+
711
object Test extends dotty.runtime.LegacyApp {
8-
//val x = new Foo(1).foo.apply(2)
9-
val y = new Foo(1).bar.result(2)
10-
assert(y == 3, y)
11-
//assert(x == 3, x)
12+
13+
def Foo(a: Int) = {
14+
class Bar { def result(x: Int) = x + a }
15+
new Bar().result(2)
16+
}
17+
18+
val x1 = new Foo(1).bar.result(2)
19+
assert(x1 == 3, s"x1 = $x1")
20+
val x2 = Foo(1)
21+
assert(x2 == 3, s"x2 = $x2")
22+
val x3 = new Foo(1).foo.apply(2)
23+
assert(x3 == 3, s"x3 = $x3")
24+
val x4 = new VFoo(1).foo.apply(2)
25+
assert(x4 == 3, s"x4 = $x4")
1226
}

0 commit comments

Comments
 (0)