@@ -2814,25 +2814,32 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
2814
2814
MatchTypeTrace .noMatches(scrut, cases)
2815
2815
NoType
2816
2816
2817
- inFrozenConstraint {
2818
- // Empty types break the basic assumption that if a scrutinee and a
2819
- // pattern are disjoint it's OK to reduce passed that pattern. Indeed,
2820
- // empty types viewed as a set of value is always a subset of any other
2821
- // types. As a result, we first check that the scrutinee isn't empty
2822
- // before proceeding with reduction. See `tests/neg/6570.scala` and
2823
- // `6570-1.scala` for examples that exploit emptiness to break match
2824
- // type soundness.
2825
-
2826
- // If we revered the uncertainty case of this empty check, that is,
2827
- // `!provablyNonEmpty` instead of `provablyEmpty`, that would be
2828
- // obviously sound, but quite restrictive. With the current formulation,
2829
- // we need to be careful that `provablyEmpty` covers all the conditions
2830
- // used to conclude disjointness in `provablyDisjoint`.
2831
- if (provablyEmpty(scrut))
2832
- NoType
2833
- else
2834
- recur(cases)
2817
+ // inFrozenConstraint is not sufficient here as it doesn't prevent
2818
+ // parameters of type lambdas from being added to `constraint`, see
2819
+ // ConstraintHandling.canConstrain and tests/neg/9107.scala.
2820
+ val saved = constraint
2821
+ try {
2822
+ inFrozenConstraint {
2823
+ // Empty types break the basic assumption that if a scrutinee and a
2824
+ // pattern are disjoint it's OK to reduce passed that pattern. Indeed,
2825
+ // empty types viewed as a set of value is always a subset of any other
2826
+ // types. As a result, we first check that the scrutinee isn't empty
2827
+ // before proceeding with reduction. See `tests/neg/6570.scala` and
2828
+ // `6570-1.scala` for examples that exploit emptiness to break match
2829
+ // type soundness.
2830
+
2831
+ // If we reversed the uncertainty case of this empty check, that is,
2832
+ // `!provablyNonEmpty` instead of `provablyEmpty`, that would be
2833
+ // obviously sound, but quite restrictive. With the current formulation,
2834
+ // we need to be careful that `provablyEmpty` covers all the conditions
2835
+ // used to conclude disjointness in `provablyDisjoint`.
2836
+ if (provablyEmpty(scrut))
2837
+ NoType
2838
+ else
2839
+ recur(cases)
2840
+ }
2835
2841
}
2842
+ finally constraint = saved
2836
2843
}
2837
2844
}
2838
2845
0 commit comments