@@ -43,8 +43,8 @@ sealed abstract class GadtConstraint extends Showable {
43
43
*/
44
44
def contains (sym : Symbol )(using Context ): Boolean
45
45
46
- def isEmpty : Boolean
47
- final def nonEmpty : Boolean = ! isEmpty
46
+ /** GADT constraint narrows bounds of at least one variable */
47
+ def isNarrowing : Boolean
48
48
49
49
/** See [[ConstraintHandling.approximation ]] */
50
50
def approximation (sym : Symbol , fromBelow : Boolean )(using Context ): Type
@@ -61,13 +61,15 @@ final class ProperGadtConstraint private(
61
61
private var myConstraint : Constraint ,
62
62
private var mapping : SimpleIdentityMap [Symbol , TypeVar ],
63
63
private var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ],
64
+ private var wasConstrained : Boolean
64
65
) extends GadtConstraint with ConstraintHandling {
65
66
import dotty .tools .dotc .config .Printers .{gadts , gadtsConstr }
66
67
67
68
def this () = this (
68
69
myConstraint = new OrderingConstraint (SimpleIdentityMap .empty, SimpleIdentityMap .empty, SimpleIdentityMap .empty),
69
70
mapping = SimpleIdentityMap .empty,
70
- reverseMapping = SimpleIdentityMap .empty
71
+ reverseMapping = SimpleIdentityMap .empty,
72
+ wasConstrained = false
71
73
)
72
74
73
75
/** Exposes ConstraintHandling.subsumes */
@@ -149,20 +151,24 @@ final class ProperGadtConstraint private(
149
151
if (ntTvar ne null ) stripInternalTypeVar(ntTvar) else bound
150
152
case _ => bound
151
153
}
152
- (
153
- internalizedBound match {
154
- case boundTvar : TypeVar =>
155
- if (boundTvar eq symTvar) true
156
- else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
157
- else addLess(boundTvar.origin, symTvar.origin)
158
- case bound =>
159
- addBoundTransitively(symTvar.origin, bound, isUpper)
160
- }
161
- ).showing({
154
+
155
+ val saved = constraint
156
+ val result = internalizedBound match
157
+ case boundTvar : TypeVar =>
158
+ if (boundTvar eq symTvar) true
159
+ else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
160
+ else addLess(boundTvar.origin, symTvar.origin)
161
+ case bound =>
162
+ addBoundTransitively(symTvar.origin, bound, isUpper)
163
+
164
+ gadts.println {
162
165
val descr = if (isUpper) " upper" else " lower"
163
166
val op = if (isUpper) " <:" else " >:"
164
167
i " adding $descr bound $sym $op $bound = $result"
165
- }, gadts)
168
+ }
169
+
170
+ if constraint ne saved then wasConstrained = true
171
+ result
166
172
}
167
173
168
174
override def isLess (sym1 : Symbol , sym2 : Symbol )(using Context ): Boolean =
@@ -193,6 +199,8 @@ final class ProperGadtConstraint private(
193
199
194
200
override def contains (sym : Symbol )(using Context ): Boolean = mapping(sym) ne null
195
201
202
+ def isNarrowing : Boolean = wasConstrained
203
+
196
204
override def approximation (sym : Symbol , fromBelow : Boolean )(using Context ): Type = {
197
205
val res = approximation(tvarOrError(sym).origin, fromBelow = fromBelow)
198
206
gadts.println(i " approximating $sym ~> $res" )
@@ -202,19 +210,19 @@ final class ProperGadtConstraint private(
202
210
override def fresh : GadtConstraint = new ProperGadtConstraint (
203
211
myConstraint,
204
212
mapping,
205
- reverseMapping
213
+ reverseMapping,
214
+ wasConstrained
206
215
)
207
216
208
217
def restore (other : GadtConstraint ): Unit = other match {
209
218
case other : ProperGadtConstraint =>
210
219
this .myConstraint = other.myConstraint
211
220
this .mapping = other.mapping
212
221
this .reverseMapping = other.reverseMapping
222
+ this .wasConstrained = other.wasConstrained
213
223
case _ => ;
214
224
}
215
225
216
- override def isEmpty : Boolean = mapping.size == 0
217
-
218
226
// ---- Protected/internal -----------------------------------------------
219
227
220
228
override protected def constraint = myConstraint
@@ -293,7 +301,7 @@ final class ProperGadtConstraint private(
293
301
294
302
override def isLess (sym1 : Symbol , sym2 : Symbol )(using Context ): Boolean = unsupported(" EmptyGadtConstraint.isLess" )
295
303
296
- override def isEmpty : Boolean = true
304
+ override def isNarrowing : Boolean = false
297
305
298
306
override def contains (sym : Symbol )(using Context ) = false
299
307
@@ -304,7 +312,7 @@ final class ProperGadtConstraint private(
304
312
305
313
override def fresh = new ProperGadtConstraint
306
314
override def restore (other : GadtConstraint ): Unit =
307
- if (! other.isEmpty) sys.error( " cannot restore a non-empty GADTMap" )
315
+ assert (! other.isNarrowing, " cannot restore a non-empty GADTMap" )
308
316
309
317
override def debugBoundsDescription (using Context ): String = " EmptyGadtConstraint"
310
318
0 commit comments