aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/LambdaLift.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/LambdaLift.scala')
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index 42c6e85af..bffc7458e 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -94,7 +94,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
* than the previous value of `liftedowner(sym)`.
*/
def narrowLiftedOwner(sym: Symbol, owner: Symbol)(implicit ctx: Context) = {
- if (sym.owner.isTerm &&
+ if (sym.maybeOwner.isTerm &&
owner.isProperlyContainedIn(liftedOwner(sym)) &&
owner != sym) {
ctx.log(i"narrow lifted $sym to $owner")
@@ -189,10 +189,9 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
val sym = tree.symbol
def narrowTo(thisClass: ClassSymbol) = {
val enclClass = enclosure.enclosingClass
- if (!thisClass.isStaticOwner)
- narrowLiftedOwner(enclosure,
- if (enclClass.isContainedIn(thisClass)) thisClass
- else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
+ narrowLiftedOwner(enclosure,
+ if (enclClass.isContainedIn(thisClass)) thisClass
+ else enclClass) // unknown this reference, play it safe and assume the narrowest possible owner
}
tree match {
case tree: Ident =>
@@ -210,8 +209,15 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
case tree: This =>
narrowTo(tree.symbol.asClass)
case tree: DefDef =>
- if (sym.owner.isTerm && !sym.is(Label)) liftedOwner(sym) = sym.topLevelClass.owner
- else if (sym.isPrimaryConstructor && sym.owner.owner.isTerm) symSet(called, sym) += sym.owner
+ if (sym.owner.isTerm && !sym.is(Label))
+ liftedOwner(sym) = sym.enclosingClass.topLevelClass
+ // 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
+ // top-level class. This avoids possible deadlocks when a static method
+ // has to access its enclosing object from the outside.
+ else if (sym.isPrimaryConstructor && sym.owner.owner.isTerm)
+ symSet(called, sym) += sym.owner
case tree: TypeDef =>
if (sym.owner.isTerm) liftedOwner(sym) = sym.topLevelClass.owner
case tree: Template =>
@@ -360,7 +366,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
val clazz = sym.enclosingClass
val qual =
if (clazz.isStaticOwner) singleton(clazz.thisType)
- else outer(ctx.withPhase(thisTransform)).path(clazz)
+ else outer.path(clazz)
transformFollowingDeep(qual.select(sym))
}