diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-09-29 13:38:12 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-10-11 06:39:09 +0200 |
commit | d68c106cc7fc23a5d7c2a25868278e6394601e5d (patch) | |
tree | f084f6f76b40a8b7f62cc46c817e4eed94ee9ca8 /src | |
parent | 5f04610ce923bf720fbdaf2408eca07412795fe3 (diff) | |
download | dotty-d68c106cc7fc23a5d7c2a25868278e6394601e5d.tar.gz dotty-d68c106cc7fc23a5d7c2a25868278e6394601e5d.tar.bz2 dotty-d68c106cc7fc23a5d7c2a25868278e6394601e5d.zip |
Enable outer tests in pattern matcher.
And a test for this.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/transform/ExplicitOuter.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PatternMatcher.scala | 17 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 6449ab044..b736b383e 100644 --- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -13,6 +13,7 @@ import core.Names._ import core.NameOps._ import ast.Trees._ import SymUtils._ +import dotty.tools.dotc.core.Phases.Phase import util.Attachment import collection.mutable @@ -27,6 +28,8 @@ import collection.mutable * - add outer parameters to constructors * - pass outer arguments in constructor calls * - replace outer this by outer paths. + * + * needs to run after pattern matcher as it can add outer checks and force creation of $outer */ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransformer => import ExplicitOuter._ @@ -36,6 +39,10 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf override def phaseName: String = "explicitOuter" + /** List of names of phases that should have finished their processing of all compilation units + * before this phase starts + */ + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[PatternMatcher]) override def treeTransformPhase = thisTransformer.next /** Add outer accessors if a class always needs an outer pointer */ @@ -171,7 +178,7 @@ object ExplicitOuter { * result is phase dependent. In that case we use a backup strategy where we search all * definitions in the class to find the one with the OuterAccessor flag. */ - private def outerAccessor(cls: ClassSymbol)(implicit ctx: Context): Symbol = + def outerAccessor(cls: ClassSymbol)(implicit ctx: Context): Symbol = cls.info.member(outerAccName(cls)).suchThat(_ is OuterAccessor).symbol orElse cls.info.decls.find(_ is OuterAccessor).getOrElse(NoSymbol) diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 934054acf..b6e4d8f56 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -666,14 +666,16 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans val expectedOuter = expectedTp.normalizedPrefix match { //case ThisType(clazz) => This(clazz) //case NoType => Literal(Constant(true)) // fallback for SI-6183 todo? - case pre => ref(pre.typeSymbol) + case pre => ref(pre.termSymbol) } // ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` // if there's an outer accessor, otherwise the condition becomes `true` -- TODO: can we improve needsOuterTest so there's always an outerAccessor? // val outer = expectedTp.typeSymbol.newMethod(vpmName.outer, newFlags = SYNTHETIC | ARTIFACT) setInfo expectedTp.prefix - codegen._asInstanceOf(testedBinder, expectedTp).select("<outer>".toTermName).select(ctx.definitions.Object_eq).appliedTo(expectedOuter) + val expectedClass = expectedTp.dealias.classSymbol.asClass + ExplicitOuter.ensureOuterAccessors(expectedClass) + codegen._asInstanceOf(testedBinder, expectedTp).select(ExplicitOuter.outerAccessor(expectedClass)).select(ctx.definitions.Object_eq).appliedTo(expectedOuter) } } @@ -750,11 +752,12 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans override lazy val localSubstitution: Substitution = EmptySubstitution - lazy val outerTestNeeded = ( - (expectedTp.normalizedPrefix.typeSymbol ne NoSymbol) - && !expectedTp.normalizedPrefix.typeSymbol.isPackageObject - && false &&needsOuterTest(expectedTp, testedBinder.info, matchOwner) - ) + def outerTestNeeded = { + val np = expectedTp.normalizedPrefix + val ts = np.termSymbol + (ts ne NoSymbol) && needsOuterTest(expectedTp, testedBinder.info, matchOwner) + + } // the logic to generate the run-time test that follows from the fact that // a `prevBinder` is expected to have type `expectedTp` |