diff options
-rw-r--r-- | src/compiler/scala/reflect/internal/StdNames.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 23 |
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)) |