Skip to content

Commit 3f62dbd

Browse files
committed
fix: record calls to constructors in lambdaLift
1 parent 9cb97ec commit 3f62dbd

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
137137
if !enclosure.exists then throw NoPath()
138138
if enclosure == sym.enclosure then NoSymbol
139139
else
140+
/** is sym a constructor or a term that is nested in a constructor? */
140141
def nestedInConstructor(sym: Symbol): Boolean =
141142
sym.isConstructor
142143
|| sym.isTerm && nestedInConstructor(sym.enclosure)
@@ -147,7 +148,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
147148
else markFree(sym, enclosure.enclosure)
148149
if intermediate.exists then
149150
narrowLogicOwner(enclosure, intermediate)
150-
if !intermediate.isRealClass || nestedInConstructor(enclosure) then
151+
if !intermediate.isRealClass || nestedInConstructor(enclosure)then
151152
// Constructors and methods nested inside traits get the free variables
152153
// of the enclosing trait or class.
153154
// Conversely, local traits do not get free variables.
@@ -237,6 +238,9 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
237238
captureImplicitThis(tree.tpe)
238239
case tree: Select =>
239240
if isExpr(sym) && isLocal(sym) then markCalled(sym, enclosure)
241+
case tree: New =>
242+
val constr = tree.tpe.typeSymbol.primaryConstructor
243+
if enclosure.exists && isExpr(constr) then symSet(called, enclosure) += constr
240244
case tree: This =>
241245
narrowTo(tree.symbol.asClass)
242246
case tree: MemberDef if isExpr(sym) && sym.owner.isTerm =>
@@ -291,7 +295,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co
291295
val calleeOwner = normalizedCallee.owner
292296
if calleeOwner.isTerm then narrowLogicOwner(caller, logicOwner(normalizedCallee))
293297
else
294-
assert(calleeOwner.is(Trait))
298+
// assert(calleeOwner.is(Trait))
295299
// methods nested inside local trait methods cannot be lifted out
296300
// beyond the trait. Note that we can also call a trait method through
297301
// a qualifier; in that case no restriction to lifted owner arises.

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,7 @@ object LambdaLift:
129129

130130
private def proxy(sym: Symbol)(using Context): Symbol = {
131131
def liftedEnclosure(sym: Symbol) =
132-
if sym.is(Method)
133-
then deps.logicalOwner.getOrElse(sym, sym.enclosure)
134-
else sym.enclosure
132+
deps.logicalOwner.getOrElse(sym, sym.enclosure)
135133
def searchIn(enclosure: Symbol): Symbol = {
136134
if (!enclosure.exists) {
137135
def enclosures(encl: Symbol): List[Symbol] =

tests/pos/i21931.scala

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
def f() =
2-
val NotFound: Char = 'a'
3-
class crashing() {
4-
class issue() {
5-
NotFound
6-
}
7-
class Module() {
8-
val obligatory =
9-
class anonIssue() {
10-
issue()
1+
object Obj {
2+
def f() = {
3+
val NotFound: Char = 'a'
4+
class crashing() {
5+
class issue() {
6+
NotFound
7+
}
8+
class Module() {
9+
val obligatory = {
10+
def anonIssue = {
11+
issue()
12+
}
1113
}
14+
}
1215
}
1316
}
17+
}

tests/pos/i22470.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait A
2+
trait OuterClass
3+
trait MidClass
4+
trait InnerClass
5+
6+
object Obj:
7+
def outerDef(a: A) =
8+
new OuterClass {
9+
def midDef(): Unit = {
10+
new MidClass {
11+
val valdef = new InnerClass {
12+
def innerDef() =
13+
println(a)
14+
}
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)