@@ -141,7 +141,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
141141 */
142142 private [this ] var leftRoot : Type = _
143143
144- /** Are we forbidden from recording GADT constraints? */
144+ /** Are we forbidden from recording GADT constraints?
145+ *
146+ * This flag is set when we're already in [[Mode.GadtConstraintInference ]],
147+ * to signify that we temporarily cannot record any GADT constraints.
148+ */
145149 private [this ] var frozenGadt = false
146150
147151 protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
@@ -846,7 +850,14 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
846850 isSubType(tycon1.prefix, tycon2.prefix) && {
847851 // check both tycons to deal with the case when they are equal b/c of GADT constraint
848852 val tyconIsInjective = tycon1sym.isClass || tycon2sym.isClass
849- isSubArgs(args1, args2, tp1, tparams, inferGadtBounds = tyconIsInjective)
853+ def checkSubArgs () = isSubArgs(args1, args2, tp1, tparams)
854+ // we only record GADT constraints if tycon is guaranteed to be injective
855+ if (tyconIsInjective) checkSubArgs()
856+ else {
857+ val savedFrozenGadt = frozenGadt
858+ frozenGadt = true
859+ try checkSubArgs() finally frozenGadt = savedFrozenGadt
860+ }
850861 }
851862 if (res && touchedGADTs) GADTused = true
852863 res
@@ -1103,7 +1114,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
11031114 * @param tp1 The applied type containing `args1`
11041115 * @param tparams2 The type parameters of the type constructor applied to `args2`
11051116 */
1106- def isSubArgs (args1 : List [Type ], args2 : List [Type ], tp1 : Type , tparams2 : List [ParamInfo ], inferGadtBounds : Boolean = false ): Boolean = {
1117+ def isSubArgs (args1 : List [Type ], args2 : List [Type ], tp1 : Type , tparams2 : List [ParamInfo ]): Boolean = {
11071118 /** The bounds of parameter `tparam`, where all references to type paramneters
11081119 * are replaced by corresponding arguments (or their approximations in the case of
11091120 * wildcard arguments).
@@ -1167,17 +1178,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
11671178 case arg1 : TypeBounds =>
11681179 compareCaptured(arg1, arg2)
11691180 case _ =>
1170- def isSub (tp : Type , pt : Type ): Boolean = {
1171- if (inferGadtBounds) isSubType(tp, pt)
1172- else {
1173- val savedFrozenGadt = frozenGadt
1174- frozenGadt = true
1175- try isSubType(tp, pt) finally frozenGadt = savedFrozenGadt
1176- }
1177- }
1178-
1179- (v > 0 || isSub(arg2, arg1)) &&
1180- (v < 0 || isSub(arg1, arg2))
1181+ (v > 0 || isSubType(arg2, arg1)) &&
1182+ (v < 0 || isSubType(arg1, arg2))
11811183 }
11821184 }
11831185
@@ -1243,7 +1245,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
12431245 * @see [[necessaryEither ]] for the GADTFlexible case
12441246 */
12451247 protected def either (op1 : => Boolean , op2 : => Boolean ): Boolean =
1246- if (ctx.mode.is(Mode .GADTflexible )) necessaryEither(op1, op2) else sufficientEither(op1, op2)
1248+ if (ctx.mode.is(Mode .GadtConstraintInference )) necessaryEither(op1, op2) else sufficientEither(op1, op2)
12471249
12481250 /** Returns true iff the result of evaluating either `op1` or `op2` is true,
12491251 * trying at the same time to keep the constraint as wide as possible.
@@ -1491,7 +1493,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
14911493 */
14921494 private def narrowGADTBounds (tr : NamedType , bound : Type , approx : ApproxState , isUpper : Boolean ): Boolean = {
14931495 val boundImprecise = approx.high || approx.low
1494- ctx.mode.is(Mode .GADTflexible ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
1496+ ctx.mode.is(Mode .GadtConstraintInference ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
14951497 val tparam = tr.symbol
14961498 gadts.println(i " narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) " above" else " below" } to $bound ${bound.toString} ${bound.isRef(tparam)}" )
14971499 if (bound.isRef(tparam)) false
0 commit comments