aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2014-09-29 13:38:12 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-10-11 06:39:09 +0200
commitd68c106cc7fc23a5d7c2a25868278e6394601e5d (patch)
treef084f6f76b40a8b7f62cc46c817e4eed94ee9ca8 /src
parent5f04610ce923bf720fbdaf2408eca07412795fe3 (diff)
downloaddotty-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.scala9
-rw-r--r--src/dotty/tools/dotc/transform/PatternMatcher.scala17
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`