@@ -212,27 +212,34 @@ object ExplicitOuter {
212
212
/** Tree references an outer class of `cls` which is not a static owner.
213
213
*/
214
214
def referencesOuter (cls : Symbol , tree : Tree )(implicit ctx : Context ): Boolean = {
215
- def isOuter (sym : Symbol ) =
215
+ def isOuterSym (sym : Symbol ) =
216
216
! 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
+ }
217
237
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)
233
239
case nw : New =>
234
240
val newCls = nw.tpe.classSymbol
235
- isOuter(newCls.owner.enclosingClass) ||
241
+ isOuterSym(newCls.owner.enclosingClass) ||
242
+ hasOuterPrefix(nw.tpe) ||
236
243
newCls.owner.isTerm && cls.isProperlyContainedIn(newCls)
237
244
// newCls might get proxies for free variables. If current class is
238
245
// properly contained in newCls, it needs an outer path to newCls access the
0 commit comments