@@ -287,14 +287,18 @@ object CaptureSet:
287
287
else
288
288
CompareResult .fail(this )
289
289
290
- def upperApprox (origin : CaptureSet )(using Context ): CaptureSet =
291
- if isConst then this
292
- else (universal /: deps) { (acc, sup) =>
293
- assert(acc.isConst)
294
- val supApprox = sup.upperApprox(this )
295
- assert(supApprox.isConst)
296
- acc ** supApprox
297
- }
290
+ private var computingApprox = false
291
+
292
+ final def upperApprox (origin : CaptureSet )(using Context ): CaptureSet =
293
+ if computingApprox then universal
294
+ else if isConst then this
295
+ else
296
+ computingApprox = true
297
+ try computeApprox(origin).ensuring(_.isConst)
298
+ finally computingApprox = false
299
+
300
+ protected def computeApprox (origin : CaptureSet )(using Context ): CaptureSet =
301
+ (universal /: deps) { (acc, sup) => acc ** sup.upperApprox(this ) }
298
302
299
303
def solve (variance : Int )(using Context ): Unit =
300
304
if variance < 0 && ! isConst then
@@ -357,9 +361,8 @@ object CaptureSet:
357
361
else CompareResult .fail(this )
358
362
else result
359
363
360
- override def upperApprox (origin : CaptureSet )(using Context ): CaptureSet =
361
- if isConst then this
362
- else if source eq origin then universal
364
+ override def computeApprox (origin : CaptureSet )(using Context ): CaptureSet =
365
+ if source eq origin then universal
363
366
else source.upperApprox(this ).map(tm)
364
367
365
368
override def propagateSolved ()(using Context ) =
@@ -382,9 +385,8 @@ object CaptureSet:
382
385
.showing(i " propagating new elems $newElems backward from $this to $source" , capt)
383
386
else r
384
387
385
- override def upperApprox (origin : CaptureSet )(using Context ): CaptureSet =
386
- if isConst then this
387
- else if source eq origin then super .upperApprox(this ).map(bimap.inverseTypeMap)
388
+ override def computeApprox (origin : CaptureSet )(using Context ): CaptureSet =
389
+ if source eq origin then super .computeApprox(this ).map(bimap.inverseTypeMap)
388
390
else source.upperApprox(this ).map(bimap)
389
391
390
392
override def toString = s " BiMapped $id( $source, elems = $elems) "
@@ -398,9 +400,8 @@ object CaptureSet:
398
400
override def addNewElems (newElems : Refs , origin : CaptureSet )(using Context , VarState ): CompareResult =
399
401
super .addNewElems(newElems.filter(p), origin)
400
402
401
- override def upperApprox (origin : CaptureSet )(using Context ): CaptureSet =
402
- if isConst then this
403
- else if source eq origin then universal
403
+ override def computeApprox (origin : CaptureSet )(using Context ): CaptureSet =
404
+ if source eq origin then universal
404
405
else source.upperApprox(this ).filter(p)
405
406
406
407
override def toString = s " ${getClass.getSimpleName}$id( $source, elems = $elems) "
0 commit comments