aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/LambdaLift.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2016-05-26 18:42:43 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2016-05-26 18:45:49 +0200
commit86213e3f200dc18b86c14edd1657a74bbd09e95b (patch)
tree2289c7ccd62b339edc6eff66f3f7a3b798d580cb /src/dotty/tools/dotc/transform/LambdaLift.scala
parent134ad7a6a172fec97dc438dd0aff3766a0f0944a (diff)
downloaddotty-86213e3f200dc18b86c14edd1657a74bbd09e95b.tar.gz
dotty-86213e3f200dc18b86c14edd1657a74bbd09e95b.tar.bz2
dotty-86213e3f200dc18b86c14edd1657a74bbd09e95b.zip
Backport from Linker: Fix to lambda lift. Fixes #1280.
CollectDependencies had incorrect handling of `Ident`s. If it had ever met an `Ident` to a symbol defined outside of current owner-chain(e.g. Predef.println) it would issue narrowTo(enclosingClass). This is very conservative and leads to memory leaks even in trivial lambdas. My lambda-lift-foo groes stronger :-)
Diffstat (limited to 'src/dotty/tools/dotc/transform/LambdaLift.scala')
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index 3ef684e55..2d12a1d3c 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -249,14 +249,21 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
else if (sym is Method) markCalled(sym, enclosure)
else if (sym.isTerm) markFree(sym, enclosure)
}
- if (sym.maybeOwner.isClass) narrowTo(sym.owner.asClass)
+ def captureImplicitThis(x: Type): Unit = {
+ x match {
+ case TermRef(x, _) => captureImplicitThis(x)
+ case x: ThisType => narrowTo(x.tref.typeSymbol.asClass)
+ case _ =>
+ }
+ }
+ captureImplicitThis(tree.tpe)
case tree: Select =>
if (sym.is(Method) && isLocal(sym)) markCalled(sym, enclosure)
case tree: This =>
narrowTo(tree.symbol.asClass)
case tree: DefDef =>
if (sym.owner.isTerm && !sym.is(Label))
- liftedOwner(sym) = sym.enclosingClass.topLevelClass
+ liftedOwner(sym) = sym.enclosingPackageClass
// this will make methods in supercall constructors of top-level classes owned
// by the enclosing package, which means they will be static.
// On the other hand, all other methods will be indirectly owned by their