summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala23
2 files changed, 24 insertions, 0 deletions
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index a59a9040bc..794ef2c31e 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -183,6 +183,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: NameType = "$outer"
val OUTER_LOCAL: NameType = "$outer " // note the space
+ val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
val SELF: NameType = "$this"
val SPECIALIZED_INSTANCE: NameType = "specInstance$"
val STAR: NameType = "*"
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index c25f33393a..080bd5f8ee 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -509,6 +509,29 @@ abstract class ExplicitOuter extends InfoTransform
matchTranslation(mch)
case _ =>
+ if (opt.experimental) { // this turned out to be expensive, hence the hacky `if` and `return`
+ tree match {
+ // for patmatvirtualiser
+ // base.<outer>.eq(o) --> base.$outer().eq(o) if there's an accessor, else the whole tree becomes TRUE
+ // TODO remove the synthetic `<outer>` method from outerFor??
+ case Apply(eqsel@Select(eqapp@Apply(sel@Select(base, outerAcc), Nil), eq), args) if outerAcc == nme.OUTER_SYNTH =>
+ val outerFor = sel.symbol.owner.toInterface // TODO: toInterface necessary?
+ val acc = outerAccessor(outerFor)
+ if(acc == NoSymbol) {
+ // println("WARNING: no outer for "+ outerFor)
+ return transform(TRUE) // urgh... drop condition if there's no accessor
+ } else {
+ // println("(base, acc)= "+(base, acc))
+ val outerSelect = localTyper typed Apply(Select(base, acc), Nil)
+ // achieves the same as: localTyper typed atPos(tree.pos)(outerPath(base, base.tpe.typeSymbol, outerFor.outerClass))
+ // println("(b, tpsym, outerForI, outerFor, outerClass)= "+ (base, base.tpe.typeSymbol, outerFor, sel.symbol.owner, outerFor.outerClass))
+ // println("outerSelect = "+ outerSelect)
+ return transform(treeCopy.Apply(tree, treeCopy.Select(eqsel, outerSelect, eq), args))
+ }
+ case _ =>
+ }
+ }
+
if (settings.Xmigration28.value) tree match {
case TypeApply(fn @ Select(qual, _), args) if fn.symbol == Object_isInstanceOf || fn.symbol == Any_isInstanceOf =>
if (isArraySeqTest(qual.tpe, args.head.tpe))