@@ -48,7 +48,7 @@ object TypeTestsCasts {
4848 * 5. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
4949 * (a) replace `Ts` with fresh type variables `Xs`
5050 * (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`
5252 * 6. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
5353 * 7. if `P` is a refinement type, FALSE
5454 * 8. otherwise, TRUE
@@ -105,8 +105,17 @@ object TypeTestsCasts {
105105 debug.println(" P1 : " + P1 .show)
106106 debug.println(" X : " + X .show)
107107
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.
108113 P1 <:< X
109114
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).
110119 maximizeType(P1 , span, fromScala2x = false )
111120
112121 val res = P1 <:< P
0 commit comments