@@ -2134,45 +2134,46 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
21342134 }
21352135 }
21362136
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)
21492159 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
21702161 }
21712162 }
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
21742169 }
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))
21762177 }
21772178}
21782179
0 commit comments