@@ -2134,45 +2134,46 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
2134
2134
}
2135
2135
}
2136
2136
2137
- var result : Type = NoType
2138
- var remainingCases = cases
2139
- while (! remainingCases.isEmpty) {
2140
- val (cas :: cass) = remainingCases
2141
- remainingCases = cass
2142
- val saved = constraint
2143
- try {
2144
- inFrozenConstraint {
2145
- val cas1 = cas match {
2146
- case cas : HKTypeLambda =>
2147
- caseLambda = constrained(cas)
2148
- caseLambda.resultType
2137
+ /** Match a single case.
2138
+ * @return Some(tp) if the match succeeds with type `tp`
2139
+ * Some(NoType) if the match fails, and there is an overlap between pattern and scrutinee
2140
+ * None if the match fails and we should consider the following cases
2141
+ * because scrutinee and pattern do not overlap
2142
+ */
2143
+ def matchCase (cas : Type ): Option [Type ] = {
2144
+ val cas1 = cas match {
2145
+ case cas : HKTypeLambda =>
2146
+ caseLambda = constrained(cas)
2147
+ caseLambda.resultType
2148
+ case _ =>
2149
+ cas
2150
+ }
2151
+ val defn .FunctionOf (pat :: Nil , body, _, _) = cas1
2152
+ if (isSubType(scrut, pat))
2153
+ // `scrut` is a subtype of `pat`: *It's a Match!*
2154
+ Some {
2155
+ caseLambda match {
2156
+ case caseLambda : HKTypeLambda =>
2157
+ val instances = paramInstances(new Array (caseLambda.paramNames.length), pat)
2158
+ instantiateParams(instances)(body)
2149
2159
case _ =>
2150
- cas
2151
- }
2152
- val defn .FunctionOf (pat :: Nil , body, _, _) = cas1
2153
- if (isSubType(scrut, pat)) {
2154
- // `scrut` is a subtype of `pat`: *It's a Match!*
2155
- result = caseLambda match {
2156
- case caseLambda : HKTypeLambda =>
2157
- val instances = paramInstances(new Array (caseLambda.paramNames.length), pat)
2158
- instantiateParams(instances)(body)
2159
- case _ =>
2160
- body
2161
- }
2162
- remainingCases = Nil
2163
- } else if (! intersecting(scrut, pat)) {
2164
- // We found a proof that `scrut` and `pat` are incompatible.
2165
- // The search continues.
2166
- } else {
2167
- // We are stuck: this match type instanciation is irreducible.
2168
- result = NoType
2169
- remainingCases = Nil
2160
+ body
2170
2161
}
2171
2162
}
2172
- }
2173
- finally constraint = saved
2163
+ else if (intersecting(scrut, pat))
2164
+ Some (NoType )
2165
+ else
2166
+ // We found a proof that `scrut` and `pat` are incompatible.
2167
+ // The search continues.
2168
+ None
2174
2169
}
2175
- result
2170
+
2171
+ def recur (cases : List [Type ]) = cases match {
2172
+ case cas :: cases1 => matchCase(cas).getOrElse(recur(cases1))
2173
+ case Nil => NoType
2174
+ }
2175
+
2176
+ inFrozenConstraint(recur(cases))
2176
2177
}
2177
2178
}
2178
2179
0 commit comments