@@ -63,7 +63,23 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
63
63
private var myInstance : TypeComparer = this
64
64
def currentInstance : TypeComparer = myInstance
65
65
66
- private var useNecessaryEither = false
66
+ private var myNecessaryConstraintsOnly = false
67
+ /** When collecting the constraints needed for a particular subtyping
68
+ * judgment to be true, we sometimes need to approximate the constraint
69
+ * set (see `TypeComparer#either` for example).
70
+ *
71
+ * Normally, this means adding extra constraints which may not be necessary
72
+ * for the subtyping judgment to be true, but if this variable is set to true
73
+ * we will instead under-approximate and keep only the constraints that must
74
+ * always be present for the subtyping judgment to hold.
75
+ *
76
+ * This is needed for GADT bounds inference to be sound, but it is also used
77
+ * when constraining a method call based on its expected type to avoid adding
78
+ * constraints that would later prevent us from typechecking method
79
+ * arguments, see or-inf.scala and and-inf.scala for examples.
80
+ */
81
+ protected def necessaryConstraintsOnly (using Context ) =
82
+ ctx.mode.is(Mode .GadtConstraintInference ) || myNecessaryConstraintsOnly
67
83
68
84
/** Is a subtype check in progress? In that case we may not
69
85
* permanently instantiate type variables, because the corresponding
@@ -134,20 +150,20 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
134
150
}
135
151
136
152
def necessarySubType (tp1 : Type , tp2 : Type ): Boolean =
137
- val saved = useNecessaryEither
138
- useNecessaryEither = true
153
+ val saved = myNecessaryConstraintsOnly
154
+ myNecessaryConstraintsOnly = true
139
155
try topLevelSubType(tp1, tp2)
140
- finally useNecessaryEither = saved
156
+ finally myNecessaryConstraintsOnly = saved
141
157
142
158
/** Use avoidance to get rid of wildcards in constraint bounds if
143
159
* we are doing a necessary comparison, or the mode is TypeVarsMissContext.
144
160
* The idea is that under either of these conditions we are not interested
145
161
* in creating a fresh type variable to replace the wildcard. I verified
146
162
* that several tests break if one or the other part of the disjunction is dropped.
147
- * (for instance, i12677.scala demands `useNecessaryEither ` in the condition)
163
+ * (for instance, i12677.scala demands `necessaryConstraintsOnly ` in the condition)
148
164
*/
149
165
override protected def approximateWildcards : Boolean =
150
- useNecessaryEither || ctx.mode.is(Mode .TypevarsMissContext )
166
+ necessaryConstraintsOnly || ctx.mode.is(Mode .TypevarsMissContext )
151
167
152
168
def testSubType (tp1 : Type , tp2 : Type ): CompareResult =
153
169
GADTused = false
@@ -1580,24 +1596,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1580
1596
1581
1597
/** Returns true iff the result of evaluating either `op1` or `op2` is true and approximates resulting constraints.
1582
1598
*
1583
- * If we're inferring GADT bounds or constraining a method based on its
1584
- * expected type, we infer only the _necessary_ constraints, this means we
1585
- * keep the smaller constraint if any, or no constraint at all. This is
1586
- * necessary for GADT bounds inference to be sound. When constraining a
1587
- * method, this avoid committing of constraints that would later prevent us
1588
- * from typechecking method arguments, see or-inf.scala and and-inf.scala for
1589
- * examples.
1599
+ * If `necessaryConstraintsOnly` is true, we keep the smaller constraint if
1600
+ * any, or no constraint at all.
1590
1601
*
1591
1602
* Otherwise, we infer _sufficient_ constraints: we try to keep the smaller of
1592
1603
* the two constraints, but if never is smaller than the other, we just pick
1593
1604
* the first one.
1594
- *
1595
- * @see [[necessaryEither ]] for the GADT / result type case
1596
- * @see [[sufficientEither ]] for the normal case
1597
1605
*/
1598
1606
protected def either (op1 : => Boolean , op2 : => Boolean ): Boolean =
1599
1607
Stats .record(" TypeComparer.either" )
1600
- if ctx.mode.is( Mode . GadtConstraintInference ) || useNecessaryEither then
1608
+ if necessaryConstraintsOnly then
1601
1609
necessaryEither(op1, op2)
1602
1610
else
1603
1611
sufficientEither(op1, op2)
@@ -1673,7 +1681,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1673
1681
* T1 & T2 <:< T3
1674
1682
* T1 <:< T2 | T3
1675
1683
*
1676
- * Unlike [[ sufficientEither ]], this method is used in GADTConstraintInference mode, when we are attempting
1684
+ * But this method is used when `useNecessaryEither` is true, like when we are attempting
1677
1685
* to infer GADT constraints that necessarily follow from the subtyping relationship. For instance, if we have
1678
1686
*
1679
1687
* enum Expr[T] {
0 commit comments