Skip to content

Commit 8b4f73f

Browse files
committed
Merge pull request #1150 from dotty-staging/change-lambdalift-fasttrack
Change lambdalift - fasttrack
2 parents a509267 + cf2fed8 commit 8b4f73f

File tree

6 files changed

+312
-92
lines changed

6 files changed

+312
-92
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class Compiler {
7575
new Constructors, // constructors changes decls in transformTemplate, no InfoTransformers should be added after it
7676
new FunctionalInterfaces,
7777
new GetClass), // getClass transformation should be applied to specialized methods
78-
List(new LambdaLift, // in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
78+
List(new LambdaLift, // in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
7979
new ElimStaticThis,
8080
new Flatten,
8181
// new DropEmptyCompanions,

src/dotty/tools/dotc/transform/ExplicitOuter.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ object ExplicitOuter {
209209
private def hasOuterParam(cls: ClassSymbol)(implicit ctx: Context): Boolean =
210210
!cls.is(Trait) && needsOuterIfReferenced(cls) && outerAccessor(cls).exists
211211

212-
/** Tree references a an outer class of `cls` which is not a static owner.
212+
/** Tree references an outer class of `cls` which is not a static owner.
213213
*/
214214
def referencesOuter(cls: Symbol, tree: Tree)(implicit ctx: Context): Boolean = {
215215
def isOuter(sym: Symbol) =
@@ -231,7 +231,12 @@ object ExplicitOuter {
231231
case _ => false
232232
}
233233
case nw: New =>
234-
isOuter(nw.tpe.classSymbol.owner.enclosingClass)
234+
val newCls = nw.tpe.classSymbol
235+
isOuter(newCls.owner.enclosingClass) ||
236+
newCls.owner.isTerm && cls.isProperlyContainedIn(newCls)
237+
// newCls might get proxies for free variables. If current class is
238+
// properly contained in newCls, it needs an outer path to newCls access the
239+
// proxies and forward them to the new instance.
235240
case _ =>
236241
false
237242
}
@@ -308,7 +313,7 @@ object ExplicitOuter {
308313
/** The path of outer accessors that references `toCls.this` starting from
309314
* the context owner's this node.
310315
*/
311-
def path(toCls: Symbol): Tree = try {
316+
def path(toCls: Symbol, start: Tree = This(ctx.owner.enclosingClass.asClass)): Tree = try {
312317
def loop(tree: Tree): Tree = {
313318
val treeCls = tree.tpe.widen.classSymbol
314319
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
@@ -317,7 +322,7 @@ object ExplicitOuter {
317322
else loop(tree.select(outerAccessor(treeCls.asClass)(outerAccessorCtx)).ensureApplied)
318323
}
319324
ctx.log(i"computing outerpath to $toCls from ${ctx.outersIterator.map(_.owner).toList}")
320-
loop(This(ctx.owner.enclosingClass.asClass))
325+
loop(start)
321326
} catch {
322327
case ex: ClassCastException =>
323328
throw new ClassCastException(i"no path exists from ${ctx.owner.enclosingClass} to $toCls")

0 commit comments

Comments
 (0)