Skip to content

Commit c96482c

Browse files
committed
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.
1 parent 699e0d8 commit c96482c

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

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

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

9494
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) = {
95-
ctx.log(i"narrow lifted $sym to $owner")
96-
if (sym.owner.skipConstructor.isTerm &&
97-
owner.isProperlyContainedIn(liftedOwner(sym))) {
95+
if (sym.owner.isTerm &&
96+
owner.isProperlyContainedIn(liftedOwner(sym)) &&
97+
owner != sym) {
98+
ctx.log(i"narrow lifted $sym to $owner")
9899
changedLiftedOwner = true
99100
liftedOwner(sym) = owner
100101
}
@@ -133,9 +134,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
133134
private def markFree(sym: Symbol, enclosure: Symbol)(implicit ctx: Context): Boolean = try {
134135
if (!enclosure.exists) throw new NoPath
135136
ctx.log(i"mark free: ${sym.showLocated} with owner ${sym.maybeOwner} marked free in $enclosure")
137+
narrowLiftedOwner(enclosure, sym.enclosingClass)
136138
(enclosure == sym.enclosure) || {
137139
ctx.debuglog(i"$enclosure != ${sym.enclosure}")
138-
narrowLiftedOwner(enclosure, sym.enclosingClass)
139140
if (enclosure.is(PackageClass) ||
140141
!markFree(sym, enclosure.skipConstructor.enclosure)) false
141142
else {
@@ -165,6 +166,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
165166
def traverse(enclMeth: Symbol, tree: Tree) = try { //debug
166167
val enclosure = enclMeth.skipConstructor
167168
val sym = tree.symbol
169+
def narrowTo(thisClass: ClassSymbol) = {
170+
val enclClass = enclosure.enclosingClass
171+
if (!thisClass.isStaticOwner)
172+
narrowLiftedOwner(enclosure,
173+
if (enclClass.isContainedIn(thisClass)) thisClass
174+
else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
175+
}
168176
tree match {
169177
case tree: Ident =>
170178
if (sym.maybeOwner.isTerm) {
@@ -173,17 +181,13 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
173181
i"attempt to refer to label $sym from nested $enclosure")
174182
else if (sym is Method) markCalled(sym, enclosure)
175183
else if (sym.isTerm) markFree(sym, enclosure)
176-
}
184+
} else if (sym.maybeOwner.isClass)
185+
narrowTo(sym.owner.asClass)
177186
case tree: Select =>
178187
if (sym.isConstructor && sym.owner.owner.isTerm)
179188
markCalled(sym, enclosure)
180189
case tree: This =>
181-
val thisClass = tree.symbol.asClass
182-
val enclClass = enclosure.enclosingClass
183-
if (!thisClass.isStaticOwner && thisClass != enclClass)
184-
narrowLiftedOwner(enclosure,
185-
if (enclClass.isContainedIn(thisClass)) thisClass
186-
else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
190+
narrowTo(tree.symbol.asClass)
187191
case tree: DefDef =>
188192
if (sym.owner.isTerm && !sym.is(Label)) liftedOwner(sym) = sym.topLevelClass.owner
189193
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)