@@ -2771,9 +2771,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2771
2771
false
2772
2772
} || tycon.derivesFrom(defn.PairClass )
2773
2773
2774
- /** Are `tp1` and `tp2` provablyDisjoint types?
2775
- *
2776
- * `true` implies that we found a proof; uncertainty defaults to `false`.
2774
+ /** Are `tp1` and `tp2` provablyDisjoint types, i.e., is `tp1 ⋔ tp2` true?
2777
2775
*
2778
2776
* Proofs rely on the following properties of Scala types:
2779
2777
*
@@ -2786,14 +2784,28 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2786
2784
* Note on soundness: the correctness of match types relies on on the
2787
2785
* property that in all possible contexts, the same match type expression
2788
2786
* is either stuck or reduces to the same case.
2787
+ *
2788
+ * This method must adhere to the specification of disjointness in SIP-56:
2789
+ * https://docs.scala-lang.org/sips/match-types-spec.html#disjointness
2790
+ *
2791
+ * The pattern matcher reachability test uses it for its own purposes, so we
2792
+ * generalize it to *also* handle type variables and their GADT bounds.
2793
+ * This is fine because match type reduction always operates under frozen
2794
+ * GADT constraints.
2795
+ *
2796
+ * Other than that generalization, `provablyDisjoint` must not depart from
2797
+ * the specified "provably disjoint" relation. In particular, it is not
2798
+ * allowed to reply `false` instead of "I don't know". It must say `true`
2799
+ * iff the spec says `true` and must say `false` iff the spec says `false`.
2789
2800
*/
2790
2801
def provablyDisjoint (tp1 : Type , tp2 : Type )(using Context ): Boolean =
2791
2802
provablyDisjoint(tp1, tp2, null )
2792
2803
2793
- def provablyDisjoint (tp1 : Type , tp2 : Type , pending : util.HashSet [(Type , Type )] | Null )(
2804
+ private def provablyDisjoint (tp1 : Type , tp2 : Type , pending : util.HashSet [(Type , Type )] | Null )(
2794
2805
using Context ): Boolean = trace(i " provable disjoint $tp1, $tp2" , matchTypes) {
2795
2806
// println(s"provablyDisjoint(${tp1.show}, ${tp2.show})")
2796
2807
2808
+ // Computes ⌈tp⌉ (see the spec), generalized to handle GADT bounds
2797
2809
@ scala.annotation.tailrec
2798
2810
def disjointnessBoundary (tp : Type ): Type = tp match
2799
2811
case tp : TypeRef =>
@@ -3344,6 +3356,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
3344
3356
MatchResult .Stuck
3345
3357
end matchSubTypeTest
3346
3358
3359
+ // See https://docs.scala-lang.org/sips/match-types-spec.html#matching
3347
3360
def matchSpeccedPatMat (spec : MatchTypeCaseSpec .SpeccedPatMat ): MatchResult =
3348
3361
/* Concreteness checking
3349
3362
*
0 commit comments