@@ -48,7 +48,7 @@ object TypeTestsCasts {
48
48
* 5. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
49
49
* (a) replace `Ts` with fresh type variables `Xs`
50
50
* (b) constrain `Xs` with `pre.F[Xs] <:< X`
51
- * (c) instantiate Xs and check `pre.F[Xs] <:< P`
51
+ * (c) maximize `pre.F[Xs]` and check `pre.F[Xs] <:< P`
52
52
* 6. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
53
53
* 7. if `P` is a refinement type, FALSE
54
54
* 8. otherwise, TRUE
@@ -105,8 +105,17 @@ object TypeTestsCasts {
105
105
debug.println(" P1 : " + P1 .show)
106
106
debug.println(" X : " + X .show)
107
107
108
+ // It does not matter if P1 is not a subtype of X.
109
+ // It just tries to infer type arguments of P1 from X if the value x
110
+ // conforms to the type skeleton pre.F[_]. Then it goes on to check
111
+ // if P1 <: P, which means the type arguments in P are trivial,
112
+ // thus no runtime checks are needed for them.
108
113
P1 <:< X
109
114
115
+ // Maximization of the type means we try to cover all possible values
116
+ // which conform to the skeleton pre.F[_] and X. Then we have to make
117
+ // sure all of them are actually of the type P, which implies that the
118
+ // type arguments in P are trivial (no runtime check needed).
110
119
maximizeType(P1 , span, fromScala2x = false )
111
120
112
121
val res = P1 <:< P
0 commit comments