@@ -20,7 +20,7 @@ class IsInstanceOfChecker extends MiniPhase {
20
20
def ensureCheckable (qual : Tree , pt : Tree ): Tree = {
21
21
if (! Checkable .checkable(qual.tpe, pt.tpe))
22
22
ctx.warning(
23
- s " the type test for ${pt} cannot be checked at runtime " ,
23
+ s " the type test for ${pt.show } cannot be checked at runtime " ,
24
24
tree.pos
25
25
)
26
26
@@ -43,16 +43,18 @@ object Checkable {
43
43
44
44
/** Whether `(x:X).isInstanceOf[P]` can be checked at runtime?
45
45
*
46
- * 0. if `P` is a singleton type, TRUE
47
- * 1. if `P` refers to an abstract type member, FALSE
48
- * 2. if `P = Array[T]`, checkable(E, T) where `E` is the element type of `X`, defaults to `Any`.
49
- * 3. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
46
+ * 1. if `P` is a singleton type, TRUE
47
+ * 2. if `P` is WildcardType, TRUE
48
+ * 3. if `P` refers to an abstract type member, FALSE
49
+ * 4. if `P = Array[T]`, checkable(E, T) where `E` is the element type of `X`, defaults to `Any`.
50
+ * 5. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
50
51
* (a) replace `Ts` with fresh type variables `Xs`
51
52
* (b) instantiate `Xs` with the constraint `pre.F[Xs] <:< X`
52
53
* (c) `pre.F[Xs] <:< P2`, where `P2` is `P` with pattern binder types (e.g., `_$1`)
53
54
* replaced with `WildcardType`.
54
- * 4. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
55
- * 5. otherwise, TRUE
55
+ * 6. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
56
+ * 7. if `P` is a refinement type, FALSE
57
+ * 8. otherwise, TRUE
56
58
*/
57
59
def checkable (X : Type , P : Type )(implicit ctx : Context ): Boolean = {
58
60
def Psym = P .dealias.typeSymbol
@@ -86,8 +88,9 @@ object Checkable {
86
88
}
87
89
}
88
90
89
- P match {
91
+ val res = P match {
90
92
case _ : SingletonType => true
93
+ case WildcardType => true
91
94
case defn.ArrayOf (tpT) =>
92
95
X match {
93
96
case defn.ArrayOf (tpE) => checkable(tpE, tpT)
@@ -96,7 +99,12 @@ object Checkable {
96
99
case tpe : AppliedType => ! isAbstract && isClassDetermined(tpe)(ctx.fresh.setFreshGADTBounds)
97
100
case AndType (tp1, tp2) => checkable(X , tp1) && checkable(X , tp2)
98
101
case OrType (tp1, tp2) => checkable(X , tp1) && checkable(X , tp2)
99
- case _ => ! isAbstract
102
+ case AnnotatedType (tp, _) => checkable(X , tp)
103
+ case _ => replaceBinderMap.apply(P ) == WildcardType || ! isAbstract
100
104
}
105
+
106
+ debug.println(i " checking ${X .show} isInstanceOf ${P } = $res" )
107
+
108
+ res
101
109
}
102
110
}
0 commit comments