@@ -22,7 +22,7 @@ object PatMat {
22
22
23
23
abstract class Node
24
24
25
- class Translator (implicit ctx : Context ) {
25
+ class Translator (resultType : Type , trans : TreeTransform )( implicit ctx : Context , info : TransformerInfo ) {
26
26
27
27
def patmatGenerated (sym : Symbol ) =
28
28
sym.is(Synthetic ) &&
@@ -100,7 +100,42 @@ object PatMat {
100
100
101
101
class TypeTest (scrut : Symbol , tpt : Tree , ons : Node , onf : Node ) extends Test (scrut, ons, onf) {
102
102
def pos = tpt.pos
103
- def condition = scrutinee.select(defn.Any_typeTest ).appliedToType(tpt.tpe)
103
+ private val expectedTp = tpt.tpe
104
+
105
+ private def outerTestNeeded (implicit ctx : Context ): Boolean = {
106
+ // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest`
107
+ // generates an outer test based on `patType.prefix` with automatically dealises.
108
+ expectedTp.dealias match {
109
+ case tref @ TypeRef (pre : SingletonType , name) =>
110
+ tref.symbol.isClass &&
111
+ ExplicitOuter .needsOuterIfReferenced(tref.symbol.asClass)
112
+ case _ =>
113
+ false
114
+ }
115
+ }
116
+
117
+ private def outerTest : Tree = trans.transformFollowingDeep {
118
+ val expectedOuter = singleton(expectedTp.normalizedPrefix)
119
+ val expectedClass = expectedTp.dealias.classSymbol.asClass
120
+ ExplicitOuter .ensureOuterAccessors(expectedClass)(ctx.withPhase(ctx.explicitOuterPhase.next))
121
+ scrutinee.ensureConforms(expectedTp)
122
+ .outerSelect(1 , expectedOuter.tpe.widen)
123
+ .select(defn.Object_eq )
124
+ .appliedTo(expectedOuter)
125
+ }
126
+
127
+ def condition = expectedTp.dealias match {
128
+ case expectedTp : SingletonType =>
129
+ val test =
130
+ if (expectedTp.widen.derivesFrom(defn.ObjectClass ))
131
+ scrutinee.ensureConforms(defn.ObjectType ).select(defn.Object_eq )
132
+ else
133
+ scrutinee.select(defn.Any_== )
134
+ test.appliedTo(singleton(expectedTp))
135
+ case _ =>
136
+ val typeTest = scrutinee.select(defn.Any_typeTest ).appliedToType(tpt.tpe)
137
+ if (outerTestNeeded) typeTest.and(outerTest) else typeTest
138
+ }
104
139
override def toString = i " TypeTest( $scrutinee: $tpt) "
105
140
}
106
141
@@ -450,7 +485,7 @@ class PatMat extends MiniPhaseTransform {
450
485
override def runsAfterGroupsOf = Set (classOf [TailRec ]) // tailrec is not capable of reversing the patmat tranformation made for tree
451
486
452
487
override def transformMatch (tree : Match )(implicit ctx : Context , info : TransformerInfo ): Tree = {
453
- val translated = new Translator ()(ctx ).translateMatch(tree)
488
+ val translated = new Translator (tree.tpe, this ).translateMatch(tree)
454
489
455
490
// check exhaustivity and unreachability
456
491
val engine = new patmat.SpaceEngine
0 commit comments