@@ -2848,25 +2848,32 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
2848
2848
MatchTypeTrace .noMatches(scrut, cases)
2849
2849
NoType
2850
2850
2851
- inFrozenConstraint {
2852
- // Empty types break the basic assumption that if a scrutinee and a
2853
- // pattern are disjoint it's OK to reduce passed that pattern. Indeed,
2854
- // empty types viewed as a set of value is always a subset of any other
2855
- // types. As a result, we first check that the scrutinee isn't empty
2856
- // before proceeding with reduction. See `tests/neg/6570.scala` and
2857
- // `6570-1.scala` for examples that exploit emptiness to break match
2858
- // type soundness.
2859
-
2860
- // If we revered the uncertainty case of this empty check, that is,
2861
- // `!provablyNonEmpty` instead of `provablyEmpty`, that would be
2862
- // obviously sound, but quite restrictive. With the current formulation,
2863
- // we need to be careful that `provablyEmpty` covers all the conditions
2864
- // used to conclude disjointness in `provablyDisjoint`.
2865
- if (provablyEmpty(scrut))
2866
- NoType
2867
- else
2868
- recur(cases)
2851
+ // inFrozenConstraint is not sufficient here as it doesn't prevent
2852
+ // parameters of type lambdas from being added to `constraint`, see
2853
+ // ConstraintHandling.canConstrain and tests/neg/9107.scala.
2854
+ val saved = constraint
2855
+ try {
2856
+ inFrozenConstraint {
2857
+ // Empty types break the basic assumption that if a scrutinee and a
2858
+ // pattern are disjoint it's OK to reduce passed that pattern. Indeed,
2859
+ // empty types viewed as a set of value is always a subset of any other
2860
+ // types. As a result, we first check that the scrutinee isn't empty
2861
+ // before proceeding with reduction. See `tests/neg/6570.scala` and
2862
+ // `6570-1.scala` for examples that exploit emptiness to break match
2863
+ // type soundness.
2864
+
2865
+ // If we reversed the uncertainty case of this empty check, that is,
2866
+ // `!provablyNonEmpty` instead of `provablyEmpty`, that would be
2867
+ // obviously sound, but quite restrictive. With the current formulation,
2868
+ // we need to be careful that `provablyEmpty` covers all the conditions
2869
+ // used to conclude disjointness in `provablyDisjoint`.
2870
+ if (provablyEmpty(scrut))
2871
+ NoType
2872
+ else
2873
+ recur(cases)
2874
+ }
2869
2875
}
2876
+ finally constraint = saved
2870
2877
}
2871
2878
}
2872
2879
0 commit comments