@@ -7,6 +7,7 @@ import Contexts._
7
7
import Symbols ._
8
8
import Types ._
9
9
import StdNames ._
10
+ import NameKinds .OuterSelectName
10
11
11
12
import ast .tpd ._
12
13
import util .EqHashMap
@@ -797,7 +798,15 @@ class Semantic {
797
798
res.call(id.symbol, args, superType = NoType , source = expr)
798
799
799
800
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)
801
810
802
811
case _ : This =>
803
812
cases(expr.tpe, thisV, klass, expr)
@@ -963,6 +972,40 @@ class Semantic {
963
972
964
973
}
965
974
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
+
966
1009
/** Compute the outer value that correspond to `tref.prefix` */
967
1010
def outerValue (tref : TypeRef , thisV : Addr , klass : ClassSymbol , source : Tree ): Contextual [Result ] =
968
1011
val cls = tref.classSymbol.asClass
0 commit comments