@@ -43,8 +43,8 @@ sealed abstract class GadtConstraint extends Showable {
4343 */
4444 def contains (sym : Symbol )(using Context ): Boolean
4545
46- def isEmpty : Boolean
47- final def nonEmpty : Boolean = ! isEmpty
46+ /** GADT constraint narrows bounds of at least one variable */
47+ def isNarrowing : Boolean
4848
4949 /** See [[ConstraintHandling.approximation ]] */
5050 def approximation (sym : Symbol , fromBelow : Boolean )(using Context ): Type
@@ -61,13 +61,15 @@ final class ProperGadtConstraint private(
6161 private var myConstraint : Constraint ,
6262 private var mapping : SimpleIdentityMap [Symbol , TypeVar ],
6363 private var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ],
64+ private var wasConstrained : Boolean
6465) extends GadtConstraint with ConstraintHandling {
6566 import dotty .tools .dotc .config .Printers .{gadts , gadtsConstr }
6667
6768 def this () = this (
6869 myConstraint = new OrderingConstraint (SimpleIdentityMap .empty, SimpleIdentityMap .empty, SimpleIdentityMap .empty),
6970 mapping = SimpleIdentityMap .empty,
70- reverseMapping = SimpleIdentityMap .empty
71+ reverseMapping = SimpleIdentityMap .empty,
72+ wasConstrained = false
7173 )
7274
7375 /** Exposes ConstraintHandling.subsumes */
@@ -149,20 +151,24 @@ final class ProperGadtConstraint private(
149151 if (ntTvar ne null ) stripInternalTypeVar(ntTvar) else bound
150152 case _ => bound
151153 }
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 {
162165 val descr = if (isUpper) " upper" else " lower"
163166 val op = if (isUpper) " <:" else " >:"
164167 i " adding $descr bound $sym $op $bound = $result"
165- }, gadts)
168+ }
169+
170+ if constraint ne saved then wasConstrained = true
171+ result
166172 }
167173
168174 override def isLess (sym1 : Symbol , sym2 : Symbol )(using Context ): Boolean =
@@ -193,6 +199,8 @@ final class ProperGadtConstraint private(
193199
194200 override def contains (sym : Symbol )(using Context ): Boolean = mapping(sym) ne null
195201
202+ def isNarrowing : Boolean = wasConstrained
203+
196204 override def approximation (sym : Symbol , fromBelow : Boolean )(using Context ): Type = {
197205 val res = approximation(tvarOrError(sym).origin, fromBelow = fromBelow)
198206 gadts.println(i " approximating $sym ~> $res" )
@@ -202,19 +210,19 @@ final class ProperGadtConstraint private(
202210 override def fresh : GadtConstraint = new ProperGadtConstraint (
203211 myConstraint,
204212 mapping,
205- reverseMapping
213+ reverseMapping,
214+ wasConstrained
206215 )
207216
208217 def restore (other : GadtConstraint ): Unit = other match {
209218 case other : ProperGadtConstraint =>
210219 this .myConstraint = other.myConstraint
211220 this .mapping = other.mapping
212221 this .reverseMapping = other.reverseMapping
222+ this .wasConstrained = other.wasConstrained
213223 case _ => ;
214224 }
215225
216- override def isEmpty : Boolean = mapping.size == 0
217-
218226 // ---- Protected/internal -----------------------------------------------
219227
220228 override protected def constraint = myConstraint
@@ -293,7 +301,7 @@ final class ProperGadtConstraint private(
293301
294302 override def isLess (sym1 : Symbol , sym2 : Symbol )(using Context ): Boolean = unsupported(" EmptyGadtConstraint.isLess" )
295303
296- override def isEmpty : Boolean = true
304+ override def isNarrowing : Boolean = false
297305
298306 override def contains (sym : Symbol )(using Context ) = false
299307
@@ -304,7 +312,7 @@ final class ProperGadtConstraint private(
304312
305313 override def fresh = new ProperGadtConstraint
306314 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" )
308316
309317 override def debugBoundsDescription (using Context ): String = " EmptyGadtConstraint"
310318
0 commit comments