Skip to content

Commit beb2e41

Browse files
committed
Fix #2883: Avoid capturing fields accessed in constructor
In LambdaLift, fields used only in the constructor of a class should not be marked free in the enclosing class.
1 parent 1d30bd0 commit beb2e41

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
202202
ctx.debuglog(i"mark free: ${sym.showLocated} with owner ${sym.maybeOwner} marked free in $enclosure")
203203
val intermediate =
204204
if (enclosure.is(PackageClass)) enclosure
205+
else if (enclosure.isConstructor) markFree(sym, enclosure.owner.enclosure)
205206
else markFree(sym, enclosure.enclosure)
206207
narrowLiftedOwner(enclosure, intermediate orElse sym.enclosingClass)
207208
if (!intermediate.isRealClass || enclosure.isConstructor) {

tests/run/i2883.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

tests/run/i2883.scala

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Wrapper(val value: Int)
2+
3+
abstract class Foo(val x: Int)
4+
5+
class Test {
6+
def foo(wrapper: Wrapper): Unit = {
7+
new Foo(wrapper.value) {}
8+
}
9+
}
10+
object Test extends App {
11+
def foo(wrapper: Wrapper): Foo =
12+
new Foo(wrapper.value) {}
13+
def printFields(obj: Any) =
14+
println(obj.getClass.getDeclaredFields.map(_.toString).sorted.deep.mkString("\n"))
15+
printFields(foo(new Wrapper(1)))
16+
}

0 commit comments

Comments
 (0)