diff options
author | Dmitry Petrashko <dark@d-d.me> | 2014-12-15 10:51:16 +0100 |
---|---|---|
committer | Dmitry Petrashko <dark@d-d.me> | 2014-12-15 10:51:16 +0100 |
commit | 8088ef2d162d877119b762ae156824d19afb5f6d (patch) | |
tree | 76dcba598c786ad9a0f6eef7464479c920551c1d /src/dotty/tools/dotc | |
parent | d65be09e86302bdf690a6da7a22d7338e869de43 (diff) | |
parent | c96482cfd99c04855b48dc146c9e2daf0cbaef87 (diff) | |
download | dotty-8088ef2d162d877119b762ae156824d19afb5f6d.tar.gz dotty-8088ef2d162d877119b762ae156824d19afb5f6d.tar.bz2 dotty-8088ef2d162d877119b762ae156824d19afb5f6d.zip |
Merge pull request #275 from dotty-staging/fix/#266-lambdaLift
Fix/#266 lambda lift
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/TypeErasure.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/LambdaLift.scala | 26 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 7 |
3 files changed, 24 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/TypeErasure.scala b/src/dotty/tools/dotc/TypeErasure.scala index 39eb7a254..de956ca6a 100644 --- a/src/dotty/tools/dotc/TypeErasure.scala +++ b/src/dotty/tools/dotc/TypeErasure.scala @@ -287,8 +287,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild else this(parent) case tp: TermRef => this(tp.widen) - case ThisType(_) => - this(tp.widen) + case tp: ThisType => + this(tp.cls.typeRef) case SuperType(thistpe, supertpe) => SuperType(this(thistpe), this(supertpe)) case ExprType(rt) => diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala index 512e19838..95c5cd529 100644 --- a/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -91,9 +91,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 } @@ -132,9 +133,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 { @@ -164,6 +165,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) { @@ -172,17 +180,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 diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index 5c45f4fc5..652536011 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -154,6 +154,13 @@ class TreeChecker { super.typedSelect(tree, pt) } + override def typedThis(tree: untpd.This)(implicit ctx: Context) = { + val res = super.typedThis(tree) + val cls = res.symbol + assert(cls.isStaticOwner || ctx.owner.isContainedIn(cls), i"error while typing $tree, ${ctx.owner} is not contained in $cls") + res + } + private def checkOwner(tree: untpd.Tree)(implicit ctx: Context): Unit = { def ownerMatches(symOwner: Symbol, ctxOwner: Symbol): Boolean = symOwner == ctxOwner || |