diff options
author | Martin Odersky <odersky@gmail.com> | 2014-12-12 17:39:00 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-12-12 17:39:13 +0100 |
commit | c96482cfd99c04855b48dc146c9e2daf0cbaef87 (patch) | |
tree | 7fad356c30b21e4f834ff3f3a3486f79ae8c647f /src/dotty/tools/dotc/transform/LambdaLift.scala | |
parent | 699e0d829c7bc3e3bf82776b311d9dd43aa379ac (diff) | |
download | dotty-c96482cfd99c04855b48dc146c9e2daf0cbaef87.tar.gz dotty-c96482cfd99c04855b48dc146c9e2daf0cbaef87.tar.bz2 dotty-c96482cfd99c04855b48dc146c9e2daf0cbaef87.zip |
Fixed narrowLiftedOwner in LambdaLift
A lot of cases were missing before and caused failures
in the newly added test in TreeChecker#typedThis.
Now we assure that all this references appear inside
the referenced class.
Diffstat (limited to 'src/dotty/tools/dotc/transform/LambdaLift.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/LambdaLift.scala | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala index 944dac208..0b355c5a5 100644 --- a/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -92,9 +92,10 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform } def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) = { - ctx.log(i"narrow lifted $sym to $owner") - if (sym.owner.skipConstructor.isTerm && - owner.isProperlyContainedIn(liftedOwner(sym))) { + if (sym.owner.isTerm && + owner.isProperlyContainedIn(liftedOwner(sym)) && + owner != sym) { + ctx.log(i"narrow lifted $sym to $owner") changedLiftedOwner = true liftedOwner(sym) = owner } @@ -133,9 +134,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform private def markFree(sym: Symbol, enclosure: Symbol)(implicit ctx: Context): Boolean = try { if (!enclosure.exists) throw new NoPath ctx.log(i"mark free: ${sym.showLocated} with owner ${sym.maybeOwner} marked free in $enclosure") + narrowLiftedOwner(enclosure, sym.enclosingClass) (enclosure == sym.enclosure) || { ctx.debuglog(i"$enclosure != ${sym.enclosure}") - narrowLiftedOwner(enclosure, sym.enclosingClass) if (enclosure.is(PackageClass) || !markFree(sym, enclosure.skipConstructor.enclosure)) false else { @@ -165,6 +166,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform def traverse(enclMeth: Symbol, tree: Tree) = try { //debug val enclosure = enclMeth.skipConstructor val sym = tree.symbol + def narrowTo(thisClass: ClassSymbol) = { + val enclClass = enclosure.enclosingClass + if (!thisClass.isStaticOwner) + narrowLiftedOwner(enclosure, + if (enclClass.isContainedIn(thisClass)) thisClass + else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner + } tree match { case tree: Ident => if (sym.maybeOwner.isTerm) { @@ -173,17 +181,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform i"attempt to refer to label $sym from nested $enclosure") else if (sym is Method) markCalled(sym, enclosure) else if (sym.isTerm) markFree(sym, enclosure) - } + } else if (sym.maybeOwner.isClass) + narrowTo(sym.owner.asClass) case tree: Select => if (sym.isConstructor && sym.owner.owner.isTerm) markCalled(sym, enclosure) case tree: This => - val thisClass = tree.symbol.asClass - val enclClass = enclosure.enclosingClass - if (!thisClass.isStaticOwner && thisClass != enclClass) - narrowLiftedOwner(enclosure, - if (enclClass.isContainedIn(thisClass)) thisClass - else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner + narrowTo(tree.symbol.asClass) case tree: DefDef => if (sym.owner.isTerm && !sym.is(Label)) liftedOwner(sym) = sym.topLevelClass.owner else if (sym.isPrimaryConstructor && sym.owner.owner.isTerm) symSet(called, sym) += sym.owner |