@@ -7,6 +7,7 @@ import Contexts._
77import Symbols ._
88import Types ._
99import StdNames ._
10+ import NameKinds .OuterSelectName
1011
1112import ast .tpd ._
1213import util .EqHashMap
@@ -797,7 +798,15 @@ class Semantic {
797798 res.call(id.symbol, args, superType = NoType , source = expr)
798799
799800 case Select (qualifier, name) =>
800- eval(qualifier, thisV, klass).select(expr.symbol, expr)
801+ val qualRes = eval(qualifier, thisV, klass)
802+
803+ name match
804+ case OuterSelectName (_, hops) =>
805+ val SkolemType (tp) = expr.tpe
806+ val outer = resolveOuterSelect(tp.classSymbol.asClass, qualRes.value, hops, source = expr)
807+ Result (outer, qualRes.errors)
808+ case _ =>
809+ qualRes.select(expr.symbol, expr)
801810
802811 case _ : This =>
803812 cases(expr.tpe, thisV, klass, expr)
@@ -963,6 +972,40 @@ class Semantic {
963972
964973 }
965974
975+ /** Resolve outer select introduced during inlining.
976+ *
977+ * See `tpd.outerSelect` and `ElimOuterSelect`.
978+ */
979+ def resolveOuterSelect (target : ClassSymbol , thisV : Value , hops : Int , source : Tree ): Contextual [Value ] = log(" resolving outer " + target.show + " , this = " + thisV.show + " , hops = " + hops, printer, res => res.asInstanceOf [Value ].show) {
980+ // Is `target` reachable from `cls` with the given `hops`?
981+ def reachable (cls : ClassSymbol , hops : Int ): Boolean =
982+ if hops == 0 then cls == target
983+ else reachable(cls.lexicallyEnclosingClass.asClass, hops - 1 )
984+
985+ thisV match
986+ case Hot => Hot
987+
988+ case addr : Addr =>
989+ val obj = heap(addr)
990+ val curOpt = obj.klass.baseClasses.find(cls => reachable(cls, hops))
991+ curOpt match
992+ case Some (cur) =>
993+ resolveThis(target, thisV, cur, source)
994+
995+ case None =>
996+ report.warning(" unexpected outerSelect, thisV = " + thisV + " , target = " + target.show + " , hops = " + hops, source.srcPos)
997+ Cold
998+
999+ case RefSet (refs) =>
1000+ refs.map(ref => resolveOuterSelect(target, ref, hops, source)).join
1001+
1002+ case fun : Fun =>
1003+ report.warning(" unexpected thisV = " + thisV + " , target = " + target.show + " , hops = " + hops, source.srcPos)
1004+ Cold
1005+
1006+ case Cold => Cold
1007+ }
1008+
9661009 /** Compute the outer value that correspond to `tref.prefix` */
9671010 def outerValue (tref : TypeRef , thisV : Addr , klass : ClassSymbol , source : Tree ): Contextual [Result ] =
9681011 val cls = tref.classSymbol.asClass
0 commit comments