Skip to content

Commit a089833

Browse files
committed
Add comments that link to relevant parts of the spec of SIP-56.
1 parent 4d4c93d commit a089833

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5162,6 +5162,16 @@ object Types extends TypeUtils {
51625162
foldOver(missing, tp)
51635163
end CheckCapturesPresent
51645164

5165+
/** Tries to convert a match type case pattern in HKTypeLambda form into a spec'ed `MatchTypeCasePattern`.
5166+
*
5167+
* This method recovers the structure of *legal patterns* as defined in SIP-56
5168+
* from the unstructured `HKTypeLambda` coming from the typer.
5169+
*
5170+
* It must adhere to the specification of legal patterns defined at
5171+
* https://docs.scala-lang.org/sips/match-types-spec.html#legal-patterns
5172+
*
5173+
* Returns `null` if the pattern in `caseLambda` is a not a legal pattern.
5174+
*/
51655175
private def tryConvertToSpecPattern(caseLambda: HKTypeLambda, pat: Type)(using Context): MatchTypeCasePattern | Null =
51665176
var typeParamRefsAccountedFor: Int = 0
51675177

0 commit comments

Comments
 (0)