diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:29:13 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:29:13 +0000 |
commit | 891a6e466b1b22b93c091d590178f7e5410f608e (patch) | |
tree | 76b24f0a7be308ca688e4bf224e406fb636e5f0f /src | |
parent | 8394676c1e47838922a1c99850592c5c86510a65 (diff) | |
download | scala-891a6e466b1b22b93c091d590178f7e5410f608e.tar.gz scala-891a6e466b1b22b93c091d590178f7e5410f608e.tar.bz2 scala-891a6e466b1b22b93c091d590178f7e5410f608e.zip |
explicitouter support for virtpatmat synthetic ...
explicitouter support for virtpatmat synthetic <outer> is turned into the actual outer accessor since pattern matching virtualisation is done during typer, not explicitouter like the real pattern matcher, we don't know what the outerAccessor is yet when emitting outer checks -- thus use a synthetic select that is transformed into the real thing during explicitouter
no review
Diffstat (limited to 'src')
-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)) |