From 5dddf7e0f7ffd5835754bd2ceedba363b15b6e0c Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Thu, 30 Jan 2025 14:35:10 +0100 Subject: [PATCH 1/2] fix: record calls to constructors in lambdaLift --- .../tools/dotc/transform/Dependencies.scala | 6 ++++- .../tools/dotc/transform/LambdaLift.scala | 4 +-- tests/pos/i21931.scala | 25 +++++++++++-------- tests/pos/i22470.scala | 17 +++++++++++++ 4 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 tests/pos/i22470.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Dependencies.scala b/compiler/src/dotty/tools/dotc/transform/Dependencies.scala index 1270c13460f4..22cff5066eb9 100644 --- a/compiler/src/dotty/tools/dotc/transform/Dependencies.scala +++ b/compiler/src/dotty/tools/dotc/transform/Dependencies.scala @@ -137,6 +137,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co if !enclosure.exists then throw NoPath() if enclosure == sym.enclosure then NoSymbol else + /** is sym a constructor or a term that is nested in a constructor? */ def nestedInConstructor(sym: Symbol): Boolean = sym.isConstructor || sym.isTerm && nestedInConstructor(sym.enclosure) @@ -237,6 +238,10 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co captureImplicitThis(tree.tpe) case tree: Select => if isExpr(sym) && isLocal(sym) then markCalled(sym, enclosure) + case tree: New => + val constr = tree.tpe.typeSymbol.primaryConstructor + if isExpr(constr) then + symSet(called, enclosure) += constr case tree: This => narrowTo(tree.symbol.asClass) case tree: MemberDef if isExpr(sym) && sym.owner.isTerm => @@ -291,7 +296,6 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co val calleeOwner = normalizedCallee.owner if calleeOwner.isTerm then narrowLogicOwner(caller, logicOwner(normalizedCallee)) else - assert(calleeOwner.is(Trait)) // methods nested inside local trait methods cannot be lifted out // beyond the trait. Note that we can also call a trait method through // a qualifier; in that case no restriction to lifted owner arises. diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala index c43392f14f06..47a280af6abc 100644 --- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -129,9 +129,7 @@ object LambdaLift: private def proxy(sym: Symbol)(using Context): Symbol = { def liftedEnclosure(sym: Symbol) = - if sym.is(Method) - then deps.logicalOwner.getOrElse(sym, sym.enclosure) - else sym.enclosure + deps.logicalOwner.getOrElse(sym, sym.enclosure) def searchIn(enclosure: Symbol): Symbol = { if (!enclosure.exists) { def enclosures(encl: Symbol): List[Symbol] = diff --git a/tests/pos/i21931.scala b/tests/pos/i21931.scala index 6765768874af..d4deb93f4c2e 100644 --- a/tests/pos/i21931.scala +++ b/tests/pos/i21931.scala @@ -1,13 +1,18 @@ -def f() = - val NotFound: Char = 'a' - class crashing() { - class issue() { - NotFound - } - class Module() { - val obligatory = - class anonIssue() { - issue() +object Test { + def f() = { + val NotFound: Char = 'a' + class crashing() { + class issue() { + NotFound + } + class Module() { + val obligatory = { + def anonIssue = { + issue() + } + anonIssue } + } } } +} diff --git a/tests/pos/i22470.scala b/tests/pos/i22470.scala new file mode 100644 index 000000000000..83599f2564fc --- /dev/null +++ b/tests/pos/i22470.scala @@ -0,0 +1,17 @@ +trait A +trait OuterClass +trait MidClass +trait InnerClass + +object Obj: + def outerDef(a: A) = + new OuterClass { + def midDef(): Unit = { + new MidClass { + val valdef = new InnerClass { + def innerDef() = + println(a) + } + } + } + } From 51c5c41227ae7d70d6fd7b5dde20336e73288e0e Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Tue, 18 Feb 2025 13:08:57 +0100 Subject: [PATCH 2/2] Review fixes --- compiler/src/dotty/tools/dotc/transform/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/Dependencies.scala b/compiler/src/dotty/tools/dotc/transform/Dependencies.scala index 22cff5066eb9..9084930b6815 100644 --- a/compiler/src/dotty/tools/dotc/transform/Dependencies.scala +++ b/compiler/src/dotty/tools/dotc/transform/Dependencies.scala @@ -240,7 +240,7 @@ abstract class Dependencies(root: ast.tpd.Tree, @constructorOnly rootContext: Co if isExpr(sym) && isLocal(sym) then markCalled(sym, enclosure) case tree: New => val constr = tree.tpe.typeSymbol.primaryConstructor - if isExpr(constr) then + if constr.exists then symSet(called, enclosure) += constr case tree: This => narrowTo(tree.symbol.asClass)