aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2014-12-15 10:51:16 +0100
committerDmitry Petrashko <dark@d-d.me>2014-12-15 10:51:16 +0100
commit8088ef2d162d877119b762ae156824d19afb5f6d (patch)
tree76dcba598c786ad9a0f6eef7464479c920551c1d /src/dotty
parentd65be09e86302bdf690a6da7a22d7338e869de43 (diff)
parentc96482cfd99c04855b48dc146c9e2daf0cbaef87 (diff)
downloaddotty-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')
-rw-r--r--src/dotty/tools/dotc/TypeErasure.scala4
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala26
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala7
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 ||