@@ -141,6 +141,9 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
141141 */
142142 private [this ] var leftRoot : Type = _
143143
144+ /** Are we forbidden from recording GADT constraints? */
145+ private [this ] var frozenGadt = false
146+
144147 protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
145148 val savedApprox = approx
146149 val savedLeftRoot = leftRoot
@@ -840,8 +843,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
840843 gadtBoundsContain(tycon1sym, tycon2) ||
841844 gadtBoundsContain(tycon2sym, tycon1)
842845 ) &&
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+ }
845851 if (res && touchedGADTs) GADTused = true
846852 res
847853 case _ =>
@@ -1097,7 +1103,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
10971103 * @param tp1 The applied type containing `args1`
10981104 * @param tparams2 The type parameters of the type constructor applied to `args2`
10991105 */
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 = {
11011107 /** The bounds of parameter `tparam`, where all references to type paramneters
11021108 * are replaced by corresponding arguments (or their approximations in the case of
11031109 * wildcard arguments).
@@ -1161,8 +1167,17 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
11611167 case arg1 : TypeBounds =>
11621168 compareCaptured(arg1, arg2)
11631169 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))
11661181 }
11671182 }
11681183
@@ -1476,7 +1491,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
14761491 */
14771492 private def narrowGADTBounds (tr : NamedType , bound : Type , approx : ApproxState , isUpper : Boolean ): Boolean = {
14781493 val boundImprecise = approx.high || approx.low
1479- ctx.mode.is(Mode .GADTflexible ) && ! frozenConstraint && ! boundImprecise && {
1494+ ctx.mode.is(Mode .GADTflexible ) && ! frozenGadt && ! frozenConstraint && ! boundImprecise && {
14801495 val tparam = tr.symbol
14811496 gadts.println(i " narrow gadt bound of $tparam: ${tparam.info} from ${if (isUpper) " above" else " below" } to $bound ${bound.toString} ${bound.isRef(tparam)}" )
14821497 if (bound.isRef(tparam)) false
0 commit comments