Skip to content

Fix/#266 lambda lift #275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
26 changes: 15 additions & 11 deletions src/dotty/tools/dotc/transform/LambdaLift.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand Down