aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/LambdaLift.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/LambdaLift.scala')
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala28
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)
}