@@ -25,6 +25,7 @@ import annotation.constructorOnly
25
25
import cc .*
26
26
import NameKinds .WildcardParamName
27
27
import MatchTypes .isConcrete
28
+ import scala .util .boundary , boundary .break
28
29
29
30
/** Provides methods to compare types.
30
31
*/
@@ -2054,6 +2055,21 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2054
2055
else op2
2055
2056
end necessaryEither
2056
2057
2058
+ /** Finds the necessary (the weakest) GADT constraint among a list of them.
2059
+ * It returns the one being subsumed by all others if exists, and `None` otherwise. */
2060
+ def necessaryGadtConstraint (constrs : List [GadtConstraint ], preGadt : GadtConstraint )(using Context ): Option [GadtConstraint ] = boundary :
2061
+ constrs match
2062
+ case Nil => break(None )
2063
+ case c0 :: constrs =>
2064
+ var weakest = c0
2065
+ for c <- constrs do
2066
+ if subsumes(weakest.constraint, c.constraint, preGadt.constraint) then
2067
+ weakest = c
2068
+ else if ! subsumes(c.constraint, weakest.constraint, preGadt.constraint) then
2069
+ // this two constraints are disjoint
2070
+ break(None )
2071
+ break(Some (weakest))
2072
+
2057
2073
inline def rollbackConstraintsUnless (inline op : Boolean ): Boolean =
2058
2074
val saved = constraint
2059
2075
var result = false
@@ -3376,6 +3392,9 @@ object TypeComparer {
3376
3392
def constrainPatternType (pat : Type , scrut : Type , forceInvariantRefinement : Boolean = false )(using Context ): Boolean =
3377
3393
comparing(_.constrainPatternType(pat, scrut, forceInvariantRefinement))
3378
3394
3395
+ def necessaryGadtConstraint (constrs : List [GadtConstraint ], preGadt : GadtConstraint )(using Context ): Option [GadtConstraint ] =
3396
+ comparing(_.necessaryGadtConstraint(constrs, preGadt))
3397
+
3379
3398
def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean = false )(using Context ): String =
3380
3399
comparing(_.explained(op, header, short))
3381
3400
0 commit comments