Skip to content

Commit 8088ef2

Browse files
committed
Merge pull request #275 from dotty-staging/fix/#266-lambdaLift
Fix/#266 lambda lift
2 parents d65be09 + c96482c commit 8088ef2

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

src/dotty/tools/dotc/TypeErasure.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
287287
else this(parent)
288288
case tp: TermRef =>
289289
this(tp.widen)
290-
case ThisType(_) =>
291-
this(tp.widen)
290+
case tp: ThisType =>
291+
this(tp.cls.typeRef)
292292
case SuperType(thistpe, supertpe) =>
293293
SuperType(this(thistpe), this(supertpe))
294294
case ExprType(rt) =>

src/dotty/tools/dotc/transform/LambdaLift.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
9191
}
9292

9393
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) = {
94-
ctx.log(i"narrow lifted $sym to $owner")
95-
if (sym.owner.skipConstructor.isTerm &&
96-
owner.isProperlyContainedIn(liftedOwner(sym))) {
94+
if (sym.owner.isTerm &&
95+
owner.isProperlyContainedIn(liftedOwner(sym)) &&
96+
owner != sym) {
97+
ctx.log(i"narrow lifted $sym to $owner")
9798
changedLiftedOwner = true
9899
liftedOwner(sym) = owner
99100
}
@@ -132,9 +133,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
132133
private def markFree(sym: Symbol, enclosure: Symbol)(implicit ctx: Context): Boolean = try {
133134
if (!enclosure.exists) throw new NoPath
134135
ctx.log(i"mark free: ${sym.showLocated} with owner ${sym.maybeOwner} marked free in $enclosure")
136+
narrowLiftedOwner(enclosure, sym.enclosingClass)
135137
(enclosure == sym.enclosure) || {
136138
ctx.debuglog(i"$enclosure != ${sym.enclosure}")
137-
narrowLiftedOwner(enclosure, sym.enclosingClass)
138139
if (enclosure.is(PackageClass) ||
139140
!markFree(sym, enclosure.skipConstructor.enclosure)) false
140141
else {
@@ -164,6 +165,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
164165
def traverse(enclMeth: Symbol, tree: Tree) = try { //debug
165166
val enclosure = enclMeth.skipConstructor
166167
val sym = tree.symbol
168+
def narrowTo(thisClass: ClassSymbol) = {
169+
val enclClass = enclosure.enclosingClass
170+
if (!thisClass.isStaticOwner)
171+
narrowLiftedOwner(enclosure,
172+
if (enclClass.isContainedIn(thisClass)) thisClass
173+
else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
174+
}
167175
tree match {
168176
case tree: Ident =>
169177
if (sym.maybeOwner.isTerm) {
@@ -172,17 +180,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
172180
i"attempt to refer to label $sym from nested $enclosure")
173181
else if (sym is Method) markCalled(sym, enclosure)
174182
else if (sym.isTerm) markFree(sym, enclosure)
175-
}
183+
} else if (sym.maybeOwner.isClass)
184+
narrowTo(sym.owner.asClass)
176185
case tree: Select =>
177186
if (sym.isConstructor && sym.owner.owner.isTerm)
178187
markCalled(sym, enclosure)
179188
case tree: This =>
180-
val thisClass = tree.symbol.asClass
181-
val enclClass = enclosure.enclosingClass
182-
if (!thisClass.isStaticOwner && thisClass != enclClass)
183-
narrowLiftedOwner(enclosure,
184-
if (enclClass.isContainedIn(thisClass)) thisClass
185-
else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
189+
narrowTo(tree.symbol.asClass)
186190
case tree: DefDef =>
187191
if (sym.owner.isTerm && !sym.is(Label)) liftedOwner(sym) = sym.topLevelClass.owner
188192
else if (sym.isPrimaryConstructor && sym.owner.owner.isTerm) symSet(called, sym) += sym.owner

src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ class TreeChecker {
154154
super.typedSelect(tree, pt)
155155
}
156156

157+
override def typedThis(tree: untpd.This)(implicit ctx: Context) = {
158+
val res = super.typedThis(tree)
159+
val cls = res.symbol
160+
assert(cls.isStaticOwner || ctx.owner.isContainedIn(cls), i"error while typing $tree, ${ctx.owner} is not contained in $cls")
161+
res
162+
}
163+
157164
private def checkOwner(tree: untpd.Tree)(implicit ctx: Context): Unit = {
158165
def ownerMatches(symOwner: Symbol, ctxOwner: Symbol): Boolean =
159166
symOwner == ctxOwner ||

0 commit comments

Comments
 (0)