summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2011-10-20 22:29:13 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2011-10-20 22:29:13 +0000
commit891a6e466b1b22b93c091d590178f7e5410f608e (patch)
tree76b24f0a7be308ca688e4bf224e406fb636e5f0f
parent8394676c1e47838922a1c99850592c5c86510a65 (diff)
downloadscala-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
-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))