@@ -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