@@ -2771,9 +2771,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
27712771 false
27722772 } || tycon.derivesFrom(defn.PairClass )
27732773
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?
27772775 *
27782776 * Proofs rely on the following properties of Scala types:
27792777 *
@@ -2786,14 +2784,28 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
27862784 * Note on soundness: the correctness of match types relies on on the
27872785 * property that in all possible contexts, the same match type expression
27882786 * 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`.
27892800 */
27902801 def provablyDisjoint (tp1 : Type , tp2 : Type )(using Context ): Boolean =
27912802 provablyDisjoint(tp1, tp2, null )
27922803
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 )(
27942805 using Context ): Boolean = trace(i " provable disjoint $tp1, $tp2" , matchTypes) {
27952806 // println(s"provablyDisjoint(${tp1.show}, ${tp2.show})")
27962807
2808+ // Computes ⌈tp⌉ (see the spec), generalized to handle GADT bounds
27972809 @ scala.annotation.tailrec
27982810 def disjointnessBoundary (tp : Type ): Type = tp match
27992811 case tp : TypeRef =>
@@ -3344,6 +3356,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33443356 MatchResult .Stuck
33453357 end matchSubTypeTest
33463358
3359+ // See https://docs.scala-lang.org/sips/match-types-spec.html#matching
33473360 def matchSpeccedPatMat (spec : MatchTypeCaseSpec .SpeccedPatMat ): MatchResult =
33483361 /* Concreteness checking
33493362 *
0 commit comments