@@ -141,7 +141,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
141
141
*/
142
142
private [this ] var leftRoot : Type = _
143
143
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
+ */
145
149
private [this ] var frozenGadt = false
146
150
147
151
protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
@@ -846,7 +850,14 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
846
850
isSubType(tycon1.prefix, tycon2.prefix) && {
847
851
// check both tycons to deal with the case when they are equal b/c of GADT constraint
848
852
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
+ }
850
861
}
851
862
if (res && touchedGADTs) GADTused = true
852
863
res
@@ -1103,7 +1114,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1103
1114
* @param tp1 The applied type containing `args1`
1104
1115
* @param tparams2 The type parameters of the type constructor applied to `args2`
1105
1116
*/
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 = {
1107
1118
/** The bounds of parameter `tparam`, where all references to type paramneters
1108
1119
* are replaced by corresponding arguments (or their approximations in the case of
1109
1120
* wildcard arguments).
@@ -1167,17 +1178,8 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1167
1178
case arg1 : TypeBounds =>
1168
1179
compareCaptured(arg1, arg2)
1169
1180
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))
1181
1183
}
1182
1184
}
1183
1185
@@ -1243,7 +1245,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1243
1245
* @see [[necessaryEither ]] for the GADTFlexible case
1244
1246
*/
1245
1247
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)
1247
1249
1248
1250
/** Returns true iff the result of evaluating either `op1` or `op2` is true,
1249
1251
* 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
1491
1493
*/
1492
1494
private def narrowGADTBounds (tr : NamedType , bound : Type , approx : ApproxState , isUpper : Boolean ): Boolean = {
1493
1495
val boundImprecise = approx.high || approx.low
1494
- ctx.mode.is(Mode .GADTflexible ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
1496
+ ctx.mode.is(Mode .GadtConstraintInference ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
1495
1497
val tparam = tr.symbol
1496
1498
gadts.println(i " narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) " above" else " below" } to $bound ${bound.toString} ${bound.isRef(tparam)}" )
1497
1499
if (bound.isRef(tparam)) false
0 commit comments