@@ -157,9 +157,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
157
157
158
158
/** Are we forbidden from recording GADT constraints? */
159
159
private var frozenGadt = false
160
- private inline def inFrozenGadt [T ](op : => T ): T = {
160
+ private inline def inFrozenGadt [T ](inline op : T ): T =
161
+ inFrozenGadtIf(true )(op)
162
+
163
+ private inline def inFrozenGadtIf [T ](cond : Boolean )(inline op : T ): T = {
161
164
val savedFrozenGadt = frozenGadt
162
- frozenGadt = true
165
+ frozenGadt = cond
163
166
try op finally frozenGadt = savedFrozenGadt
164
167
}
165
168
@@ -967,7 +970,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
967
970
* corresponding arguments are subtypes relative to their variance (see `isSubArgs`).
968
971
*/
969
972
def isMatchingApply (tp1 : Type ): Boolean = tp1 match {
970
- case AppliedType (tycon1, args1) =>
973
+ case tp1 as AppliedType (tycon1, args1) =>
971
974
// We intentionally do not dealias `tycon1` or `tycon2` here.
972
975
// `TypeApplications#appliedTo` already takes care of dealiasing type
973
976
// constructors when this can be done without affecting type
@@ -977,6 +980,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
977
980
//
978
981
// Foo[?F, ?T] <:< Foo[[X] =>> (X, String), Int]
979
982
//
983
+ // where
984
+ //
985
+ // type Foo[F[_], T] = ErasedFoo[F[T]]
986
+ //
980
987
// Naturally, we'd like to infer:
981
988
//
982
989
// ?F := [X] => (X, String)
@@ -1016,10 +1023,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1016
1023
}
1017
1024
1018
1025
val res = (
1019
- tycon1sym == tycon2sym
1020
- && isSubPrefix(tycon1.prefix, tycon2.prefix)
1021
- || byGadtBounds(tycon1sym, tycon2, fromAbove = true )
1022
- || byGadtBounds(tycon2sym, tycon1, fromAbove = false )
1026
+ tycon1sym == tycon2sym && isSubPrefix(tycon1.prefix, tycon2.prefix)
1027
+ || byGadtBounds(tycon1sym, tycon2, fromAbove = true )
1028
+ || byGadtBounds(tycon2sym, tycon1, fromAbove = false )
1023
1029
) && {
1024
1030
// There are two cases in which we can assume injectivity.
1025
1031
// First we check if either sym is a class.
@@ -1031,11 +1037,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1031
1037
// must be instantiated, making the two tycons equal
1032
1038
val tyconIsInjective =
1033
1039
(tycon1sym.isClass || tycon2sym.isClass)
1034
- && (if touchedGADTs then gadtIsInstantiated else true )
1035
- def checkSubArgs () = isSubArgs(args1, args2, tp1, tparams)
1036
- // we only record GADT constraints if *both* tycons are effectively injective
1037
- if (tyconIsInjective) checkSubArgs( )
1038
- else inFrozenGadt { checkSubArgs() }
1040
+ && (! touchedGADTs || gadtIsInstantiated)
1041
+
1042
+ inFrozenGadtIf( ! tyconIsInjective) {
1043
+ isSubArgs(args1, args2, tp1, tparams )
1044
+ }
1039
1045
}
1040
1046
if (res && touchedGADTs) GADTused = true
1041
1047
res
@@ -1544,19 +1550,19 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1544
1550
* Method name comes from the notion that we are keeping a constraint which is sufficient to satisfy
1545
1551
* one of subtyping relationships.
1546
1552
*/
1547
- private def sufficientEither (op1 : => Boolean , op2 : => Boolean ): Boolean = {
1553
+ private def sufficientEither (op1 : => Boolean , op2 : => Boolean ): Boolean =
1548
1554
val preConstraint = constraint
1549
- op1 && {
1550
- val leftConstraint = constraint
1551
- constraint = preConstraint
1552
- if (! (op2 && subsumes(leftConstraint, constraint, preConstraint))) {
1553
- if (constr != noPrinter && ! subsumes(constraint, leftConstraint, preConstraint))
1554
- constr.println(i " CUT - prefer $leftConstraint over $constraint" )
1555
- constraint = leftConstraint
1556
- }
1555
+ if op1 then
1556
+ if constraint ne preConstraint then
1557
+ // check whether `op2` generates a weaker constraint than `op1`
1558
+ val leftConstraint = constraint
1559
+ constraint = preConstraint
1560
+ if ! (op2 && subsumes(leftConstraint, constraint, preConstraint)) then
1561
+ if constr != noPrinter && ! subsumes(constraint, leftConstraint, preConstraint) then
1562
+ constr.println(i " CUT - prefer $leftConstraint over $constraint" )
1563
+ constraint = leftConstraint
1557
1564
true
1558
- } || op2
1559
- }
1565
+ else op2
1560
1566
1561
1567
/** Returns true iff the result of evaluating either `op1` or `op2` is true, keeping the smaller constraint if any.
1562
1568
* E.g., if
0 commit comments