@@ -25,6 +25,7 @@ import annotation.constructorOnly
2525import cc .*
2626import NameKinds .WildcardParamName
2727import MatchTypes .isConcrete
28+ import scala .util .boundary , boundary .break
2829
2930/** Provides methods to compare types.
3031 */
@@ -2054,6 +2055,21 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
20542055 else op2
20552056 end necessaryEither
20562057
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+
20572073 inline def rollbackConstraintsUnless (inline op : Boolean ): Boolean =
20582074 val saved = constraint
20592075 var result = false
@@ -3376,6 +3392,9 @@ object TypeComparer {
33763392 def constrainPatternType (pat : Type , scrut : Type , forceInvariantRefinement : Boolean = false )(using Context ): Boolean =
33773393 comparing(_.constrainPatternType(pat, scrut, forceInvariantRefinement))
33783394
3395+ def necessaryGadtConstraint (constrs : List [GadtConstraint ], preGadt : GadtConstraint )(using Context ): Option [GadtConstraint ] =
3396+ comparing(_.necessaryGadtConstraint(constrs, preGadt))
3397+
33793398 def explained [T ](op : ExplainingTypeComparer => T , header : String = " Subtype trace:" , short : Boolean = false )(using Context ): String =
33803399 comparing(_.explained(op, header, short))
33813400
0 commit comments