Skip to content

Commit 034969d

Browse files
committed
Handle supercalls in inner classes correctly
The previous fix was too coarse. We need to move an anonymous function in a supercall towards the call, we just have to make sure it's not in the directly enclosing class.
1 parent 9ec176f commit 034969d

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,17 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
143143
/** Set `liftedOwner(sym)` to `owner` if `owner` is more deeply nested
144144
* than the previous value of `liftedowner(sym)`.
145145
*/
146-
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) =
146+
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context): Unit =
147147
if (sym.maybeOwner.isTerm &&
148148
owner.isProperlyContainedIn(liftedOwner(sym)) &&
149-
!sym.is(InSuperCall) &&
150149
owner != sym) {
151-
ctx.log(i"narrow lifted $sym to $owner")
152-
changedLiftedOwner = true
153-
liftedOwner(sym) = owner
150+
if (sym.is(InSuperCall) && owner.isProperlyContainedIn(sym.enclosingClass))
151+
narrowLiftedOwner(sym, sym.enclosingClass)
152+
else {
153+
ctx.log(i"narrow lifted $sym to $owner")
154+
changedLiftedOwner = true
155+
liftedOwner(sym) = owner
156+
}
154157
}
155158

156159
/** Mark symbol `sym` as being free in `enclosure`, unless `sym` is defined

tests/run/i2163.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
class Base(f: Int => Int) {
2-
println(f(3))
2+
def result = f(3)
33
}
44

55
class Child(x: Int) extends Base(y => x + y)
66

7+
class Outer(z: Int) {
8+
class Base(f: Int => Int) {
9+
def result = f(3)
10+
}
11+
12+
class Child(x: Int) extends Base(y => x + y + z)
13+
}
14+
715
object Test {
8-
def main(args: Array[String]): Unit = new Child(4)
16+
def main(args: Array[String]): Unit = {
17+
assert(new Child(4).result == 7)
18+
val o = new Outer(2)
19+
assert(new o.Child(2).result == 7)
20+
}
921
}

0 commit comments

Comments
 (0)