Skip to content

Commit 1604976

Browse files
committed
Refinements to referencesOuter
In a New we need to decide based on the prefix of the type of object created.
1 parent 2c357e0 commit 1604976

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

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

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -212,27 +212,34 @@ object ExplicitOuter {
212212
/** 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 = {
215-
def isOuter(sym: Symbol) =
215+
def isOuterSym(sym: Symbol) =
216216
!sym.isStaticOwner && cls.isProperlyContainedIn(sym)
217+
def isOuterRef(ref: Type): Boolean = ref match {
218+
case ref: ThisType =>
219+
isOuterSym(ref.cls)
220+
case ref: TermRef =>
221+
if (ref.prefix ne NoPrefix)
222+
!ref.symbol.isStatic && isOuterRef(ref.prefix)
223+
else if (ref.symbol is Hoistable)
224+
// ref.symbol will be placed in enclosing class scope by LambdaLift, so it might need
225+
// an outer path then.
226+
isOuterSym(ref.symbol.owner.enclosingClass)
227+
else
228+
// ref.symbol will get a proxy in immediately enclosing class. If this properly
229+
// contains the current class, it needs an outer path.
230+
ctx.owner.enclosingClass.owner.enclosingClass.isContainedIn(ref.symbol.owner)
231+
case _ => false
232+
}
233+
def hasOuterPrefix(tp: Type) = tp match {
234+
case TypeRef(prefix, _) => isOuterRef(prefix)
235+
case _ => false
236+
}
217237
tree match {
218-
case thisTree @ This(_) =>
219-
isOuter(thisTree.symbol)
220-
case id: Ident =>
221-
id.tpe match {
222-
case ref @ TermRef(NoPrefix, _) =>
223-
if (ref.symbol is Hoistable)
224-
// ref.symbol will be placed in enclosing class scope by LambdaLift, so it might need
225-
// an outer path then.
226-
isOuter(ref.symbol.owner.enclosingClass)
227-
else
228-
// ref.symbol will get a proxy in immediately enclosing class. If this properly
229-
// contains the current class, it needs an outer path.
230-
ctx.owner.enclosingClass.owner.enclosingClass.isContainedIn(ref.symbol.owner)
231-
case _ => false
232-
}
238+
case _: This | _: Ident => isOuterRef(tree.tpe)
233239
case nw: New =>
234240
val newCls = nw.tpe.classSymbol
235-
isOuter(newCls.owner.enclosingClass) ||
241+
isOuterSym(newCls.owner.enclosingClass) ||
242+
hasOuterPrefix(nw.tpe) ||
236243
newCls.owner.isTerm && cls.isProperlyContainedIn(newCls)
237244
// newCls might get proxies for free variables. If current class is
238245
// properly contained in newCls, it needs an outer path to newCls access the

0 commit comments

Comments
 (0)