@@ -141,6 +141,9 @@ 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? */
145
+ private [this ] var frozenGadt = false
146
+
144
147
protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
145
148
val savedApprox = approx
146
149
val savedLeftRoot = leftRoot
@@ -840,8 +843,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
840
843
gadtBoundsContain(tycon1sym, tycon2) ||
841
844
gadtBoundsContain(tycon2sym, tycon1)
842
845
) &&
843
- isSubType(tycon1.prefix, tycon2.prefix) &&
844
- isSubArgs(args1, args2, tp1, tparams)
846
+ isSubType(tycon1.prefix, tycon2.prefix) && {
847
+ // check both tycons to deal with the case when they are equal b/c of GADT constraint
848
+ val tyconIsInjective = tycon1sym.isClass || tycon2sym.isClass
849
+ isSubArgs(args1, args2, tp1, tparams, inferGadtBounds = tyconIsInjective)
850
+ }
845
851
if (res && touchedGADTs) GADTused = true
846
852
res
847
853
case _ =>
@@ -1097,7 +1103,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1097
1103
* @param tp1 The applied type containing `args1`
1098
1104
* @param tparams2 The type parameters of the type constructor applied to `args2`
1099
1105
*/
1100
- def isSubArgs (args1 : List [Type ], args2 : List [Type ], tp1 : Type , tparams2 : List [ParamInfo ]): Boolean = {
1106
+ def isSubArgs (args1 : List [Type ], args2 : List [Type ], tp1 : Type , tparams2 : List [ParamInfo ], inferGadtBounds : Boolean = false ): Boolean = {
1101
1107
/** The bounds of parameter `tparam`, where all references to type paramneters
1102
1108
* are replaced by corresponding arguments (or their approximations in the case of
1103
1109
* wildcard arguments).
@@ -1161,8 +1167,17 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1161
1167
case arg1 : TypeBounds =>
1162
1168
compareCaptured(arg1, arg2)
1163
1169
case _ =>
1164
- (v > 0 || isSubType(arg2, arg1)) &&
1165
- (v < 0 || isSubType(arg1, arg2))
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))
1166
1181
}
1167
1182
}
1168
1183
@@ -1476,7 +1491,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1476
1491
*/
1477
1492
private def narrowGADTBounds (tr : NamedType , bound : Type , approx : ApproxState , isUpper : Boolean ): Boolean = {
1478
1493
val boundImprecise = approx.high || approx.low
1479
- ctx.mode.is(Mode .GADTflexible ) && ! frozenConstraint && ! boundImprecise && {
1494
+ ctx.mode.is(Mode .GADTflexible ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
1480
1495
val tparam = tr.symbol
1481
1496
gadts.println(i " narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) " above" else " below" } to $bound ${bound.toString} ${bound.isRef(tparam)}" )
1482
1497
if (bound.isRef(tparam)) false
0 commit comments