Skip to content

Commit 3ca321d

Browse files
committed
Use outer field instead of outer accessor where possible
This is a necessary first step to be able to move the field into the class constructor
1 parent 5674066 commit 3ca321d

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

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

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -386,26 +386,30 @@ object ExplicitOuter {
386386
*/
387387
def path(start: Tree = This(ctx.owner.lexicallyEnclosingClass.asClass),
388388
toCls: Symbol = NoSymbol,
389-
count: Int = -1): Tree = try {
390-
@tailrec def loop(tree: Tree, count: Int): Tree = {
391-
val treeCls = tree.tpe.widen.classSymbol
392-
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
393-
ctx.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${outerAccName(treeCls.asClass)(outerAccessorCtx)} in $treeCls")
394-
if (count == 0 || count < 0 && treeCls == toCls) tree
395-
else {
396-
val acc = outerAccessor(treeCls.asClass)(outerAccessorCtx)
397-
assert(acc.exists,
398-
i"failure to construct path from ${ctx.owner.ownersIterator.toList}%/% to `this` of ${toCls.showLocated};\n${treeCls.showLocated} does not have an outer accessor")
399-
loop(tree.select(acc).ensureApplied, count - 1)
400-
}
401-
}
402-
ctx.log(i"computing outerpath to $toCls from ${ctx.outersIterator.map(_.owner).toList}")
403-
loop(start, count)
404-
}
405-
catch {
406-
case ex: ClassCastException =>
389+
count: Int = -1): Tree =
390+
try
391+
@tailrec def loop(tree: Tree, count: Int): Tree =
392+
val treeCls = tree.tpe.widen.classSymbol
393+
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
394+
ctx.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${outerAccName(treeCls.asClass)(outerAccessorCtx)} in $treeCls")
395+
if (count == 0 || count < 0 && treeCls == toCls) tree
396+
else
397+
def selectWith(acc: Symbol): Tree =
398+
assert(acc.exists,
399+
i"failure to construct path from ${ctx.owner.ownersIterator.toList}%/% to `this` of ${toCls.showLocated};\n${treeCls.showLocated} does not have an outer accessor")
400+
tree.select(acc)
401+
val enclClass = ctx.owner.lexicallyEnclosingClass.asClass
402+
val accRef =
403+
if !enclClass.is(Trait) && tree == This(enclClass) then
404+
selectWith(outerParamAccessor(treeCls.asClass)(using outerAccessorCtx))
405+
else
406+
selectWith(outerAccessor(treeCls.asClass)(using outerAccessorCtx)).ensureApplied
407+
loop(accRef, count - 1)
408+
409+
ctx.log(i"computing outerpath to $toCls from ${ctx.outersIterator.map(_.owner).toList}")
410+
loop(start, count)
411+
catch case ex: ClassCastException =>
407412
throw new ClassCastException(i"no path exists from ${ctx.owner.enclosingClass} to $toCls")
408-
}
409413

410414
/** The outer parameter definition of a constructor if it needs one */
411415
def paramDefs(constr: Symbol): List[ValDef] =

0 commit comments

Comments
 (0)