aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/LambdaLift.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-12-12 17:39:00 +0100
committerMartin Odersky <odersky@gmail.com>2014-12-12 17:39:13 +0100
commitc96482cfd99c04855b48dc146c9e2daf0cbaef87 (patch)
tree7fad356c30b21e4f834ff3f3a3486f79ae8c647f /src/dotty/tools/dotc/transform/LambdaLift.scala
parent699e0d829c7bc3e3bf82776b311d9dd43aa379ac (diff)
downloaddotty-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.scala26
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