@@ -16,6 +16,7 @@ import NameKinds.{PatMatStdBinderName, PatMatAltsName, PatMatResultName}
16
16
import config .Printers .patmatch
17
17
import reporting .diagnostic .messages ._
18
18
import dotty .tools .dotc .ast ._
19
+ import util .Property ._
19
20
20
21
/** The pattern matching transform.
21
22
* After this phase, the only Match nodes remaining in the code are simple switches
@@ -52,6 +53,8 @@ object PatternMatcher {
52
53
/** Minimal number of cases to emit a switch */
53
54
final val MinSwitchCases = 4
54
55
56
+ val TrustedTypeTestKey : Key [Unit ] = new StickyKey [Unit ]
57
+
55
58
/** Was symbol generated by pattern matcher? */
56
59
def isPatmatGenerated (sym : Symbol )(implicit ctx : Context ): Boolean =
57
60
sym.is(Synthetic ) && sym.name.is(PatMatStdBinderName )
@@ -153,24 +156,24 @@ object PatternMatcher {
153
156
154
157
/** The different kinds of tests */
155
158
sealed abstract class Test
156
- case class TypeTest (tpt : Tree ) extends Test { // scrutinee.isInstanceOf[tpt]
159
+ case class TypeTest (tpt : Tree , trusted : Boolean ) extends Test { // scrutinee.isInstanceOf[tpt]
157
160
override def equals (that : Any ): Boolean = that match {
158
161
case that : TypeTest => this .tpt.tpe =:= that.tpt.tpe
159
162
case _ => false
160
163
}
161
164
override def hashCode : Int = tpt.tpe.hash
162
165
}
163
- case class EqualTest (tree : Tree ) extends Test { // scrutinee == tree
166
+ case class EqualTest (tree : Tree ) extends Test { // scrutinee == tree
164
167
override def equals (that : Any ): Boolean = that match {
165
168
case that : EqualTest => this .tree === that.tree
166
169
case _ => false
167
170
}
168
171
override def hashCode : Int = tree.hash
169
172
}
170
- case class LengthTest (len : Int , exact : Boolean ) extends Test // scrutinee (== | >=) len
171
- case object NonEmptyTest extends Test // !scrutinee.isEmpty
172
- case object NonNullTest extends Test // scrutinee ne null
173
- case object GuardTest extends Test // scrutinee
173
+ case class LengthTest (len : Int , exact : Boolean ) extends Test // scrutinee (== | >=) len
174
+ case object NonEmptyTest extends Test // !scrutinee.isEmpty
175
+ case object NonNullTest extends Test // scrutinee ne null
176
+ case object GuardTest extends Test // scrutinee
174
177
175
178
// ------- Generating plans from trees ------------------------
176
179
@@ -352,7 +355,12 @@ object PatternMatcher {
352
355
// begin patternPlan
353
356
swapBind(tree) match {
354
357
case Typed (pat, tpt) =>
355
- TestPlan (TypeTest (tpt), scrutinee, tree.span,
358
+ val isTrusted = pat match {
359
+ case UnApply (extractor, _, _) =>
360
+ extractor.symbol.is(Synthetic ) && extractor.symbol.owner.linkedClass.is(Case )
361
+ case _ => false
362
+ }
363
+ TestPlan (TypeTest (tpt, isTrusted), scrutinee, tree.span,
356
364
letAbstract(ref(scrutinee).cast(tpt.tpe)) { casted =>
357
365
nonNull += casted
358
366
patternPlan(casted, pat, onSuccess)
@@ -685,7 +693,7 @@ object PatternMatcher {
685
693
.select(defn.Seq_length .matchingMember(scrutinee.tpe))
686
694
.select(if (exact) defn.Int_== else defn.Int_>= )
687
695
.appliedTo(Literal (Constant (len)))
688
- case TypeTest (tpt) =>
696
+ case TypeTest (tpt, trusted ) =>
689
697
val expectedTp = tpt.tpe
690
698
691
699
// An outer test is needed in a situation like `case x: y.Inner => ...`
@@ -716,6 +724,7 @@ object PatternMatcher {
716
724
scrutinee.isInstance(expectedTp) // will be translated to an equality test
717
725
case _ =>
718
726
val typeTest = scrutinee.select(defn.Any_typeTest ).appliedToType(expectedTp)
727
+ if (trusted) typeTest.pushAttachment(TrustedTypeTestKey , ())
719
728
if (outerTestNeeded) typeTest.and(outerTest) else typeTest
720
729
}
721
730
}
@@ -899,7 +908,7 @@ object PatternMatcher {
899
908
val seen = mutable.Set [Int ]()
900
909
def showTest (test : Test ) = test match {
901
910
case EqualTest (tree) => i " EqualTest( $tree) "
902
- case TypeTest (tpt) => i " TypeTest( $tpt) "
911
+ case TypeTest (tpt, trusted ) => i " TypeTest( $tpt, trusted= $trusted ) "
903
912
case _ => test.toString
904
913
}
905
914
def showPlan (plan : Plan ): Unit =
0 commit comments