aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2015-06-19 17:01:59 +0200
committerodersky <odersky@gmail.com>2015-06-19 17:01:59 +0200
commitad6c4ad920bfed6c7c9a87850f51433260a2acf5 (patch)
tree944fa514d1d5a84229211e8f6895722b99a2d249 /src
parentc54debead6d12527469b9d69f4ab0d54cc13f7e9 (diff)
parent25304a028e6d1426b14ead4a469c362b8536d893 (diff)
downloaddotty-ad6c4ad920bfed6c7c9a87850f51433260a2acf5.tar.gz
dotty-ad6c4ad920bfed6c7c9a87850f51433260a2acf5.tar.bz2
dotty-ad6c4ad920bfed6c7c9a87850f51433260a2acf5.zip
Merge pull request #671 from dotty-staging/fix/#659-lambdalift-proxies
Fix/#659 lambdalift proxies
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala9
-rw-r--r--src/dotty/tools/dotc/transform/ExplicitOuter.scala6
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala15
3 files changed, 23 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 51011f90b..a35e0e523 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -76,8 +76,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block =
ta.assignType(untpd.Block(stats, expr), stats, expr)
- def maybeBlock(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
- if (stats.isEmpty) expr else Block(stats, expr)
+ /** Join `stats` in front of `expr` creating a new block if necessary */
+ def seq(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
+ if (stats.isEmpty) expr
+ else expr match {
+ case Block(estats, eexpr) => cpy.Block(expr)(stats ::: estats, eexpr)
+ case _ => Block(stats, expr)
+ }
def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
ta.assignType(untpd.If(cond, thenp, elsep), thenp, elsep)
diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index 912bc9b7f..eb231bfe7 100644
--- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -136,7 +136,9 @@ object ExplicitOuter {
/** A new outer accessor or param accessor */
private def newOuterSym(owner: ClassSymbol, cls: ClassSymbol, name: TermName, flags: FlagSet)(implicit ctx: Context) = {
- ctx.newSymbol(owner, name, Synthetic | flags, cls.owner.enclosingClass.typeRef, coord = cls.coord)
+ val target = cls.owner.enclosingClass.typeRef
+ val info = if (flags.is(Method)) ExprType(target) else target
+ ctx.newSymbol(owner, name, Synthetic | flags, info, coord = cls.coord)
}
/** A new param accessor for the outer field in class `cls` */
@@ -302,7 +304,7 @@ object ExplicitOuter {
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
ctx.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${outerAccName(treeCls.asClass)(outerAccessorCtx)} in $treeCls")
if (treeCls == toCls) tree
- else loop(tree select outerAccessor(treeCls.asClass)(outerAccessorCtx))
+ else loop(tree.select(outerAccessor(treeCls.asClass)(outerAccessorCtx)).ensureApplied)
}
ctx.log(i"computing outerpath to $toCls from ${ctx.outersIterator.map(_.owner).toList}")
loop(This(ctx.owner.enclosingClass.asClass))
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index bffc7458e..41d6f3c43 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -384,14 +384,23 @@ 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(ref(field).becomes(ref(param)))
+ def copyParams(rhs: Tree) = {
+ ctx.log(i"copy params ${proxies.map(_.showLocated)}%, %, own = ${ownProxies.map(_.showLocated)}%, %")
+ seq((proxies, ownProxies).zipped.map(proxyInit), 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)
}