diff options
Diffstat (limited to 'src/dotty/tools/dotc/transform/LambdaLift.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/LambdaLift.scala | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala index bffc7458e..043c92737 100644 --- a/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -384,14 +384,36 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform private def addFreeParams(tree: Tree, proxies: List[Symbol])(implicit ctx: Context, info: TransformerInfo): Tree = proxies match { case Nil => tree case proxies => + val sym = tree.symbol val ownProxies = - if (!tree.symbol.isConstructor) proxies - else proxies.map(_.copy(owner = tree.symbol, flags = Synthetic | Param)) + if (!sym.isConstructor) proxies + else proxies.map(_.copy(owner = sym, flags = Synthetic | Param)) val freeParamDefs = ownProxies.map(proxy => transformFollowingDeep(ValDef(proxy.asTerm).withPos(tree.pos)).asInstanceOf[ValDef]) + def proxyInit(field: Symbol, param: Symbol) = + transformFollowingDeep(memberRef(field).becomes(ref(param))) + + /** Map references to proxy fields `this.proxy` to proxy parameters */ + def mapProxies = new TreeMap { + override def transform(tree: Tree)(implicit ctx: Context) = tree match { + case Select(This(_), _) if proxies contains tree.symbol => + ref(tree.symbol.subst(proxies, ownProxies)) + case _ => + super.transform(tree) + } + } + + /** Initialize proxy fields from proxy parameters and map `rhs` from fields to parameters */ + def copyParams(rhs: Tree) = { + ctx.log(i"copy params ${proxies.map(_.showLocated)}%, %, own = ${ownProxies.map(_.showLocated)}%, %") + seq((proxies, ownProxies).zipped.map(proxyInit), mapProxies.transform(rhs)) + } + tree match { case tree: DefDef => - cpy.DefDef(tree)(vparamss = tree.vparamss.map(freeParamDefs ++ _)) + cpy.DefDef(tree)( + vparamss = tree.vparamss.map(freeParamDefs ++ _), + rhs = if (sym.isPrimaryConstructor) copyParams(tree.rhs) else tree.rhs) case tree: Template => cpy.Template(tree)(body = freeParamDefs ++ tree.body) } |