Skip to content

Commit 9e5fc5f

Browse files
committed
Recursion brake for upperApprox
1 parent 701747a commit 9e5fc5f

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -287,14 +287,18 @@ object CaptureSet:
287287
else
288288
CompareResult.fail(this)
289289

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) }
298302

299303
def solve(variance: Int)(using Context): Unit =
300304
if variance < 0 && !isConst then
@@ -357,9 +361,8 @@ object CaptureSet:
357361
else CompareResult.fail(this)
358362
else result
359363

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
363366
else source.upperApprox(this).map(tm)
364367

365368
override def propagateSolved()(using Context) =
@@ -382,9 +385,8 @@ object CaptureSet:
382385
.showing(i"propagating new elems $newElems backward from $this to $source", capt)
383386
else r
384387

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)
388390
else source.upperApprox(this).map(bimap)
389391

390392
override def toString = s"BiMapped$id($source, elems = $elems)"
@@ -398,9 +400,8 @@ object CaptureSet:
398400
override def addNewElems(newElems: Refs, origin: CaptureSet)(using Context, VarState): CompareResult =
399401
super.addNewElems(newElems.filter(p), origin)
400402

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
404405
else source.upperApprox(this).filter(p)
405406

406407
override def toString = s"${getClass.getSimpleName}$id($source, elems = $elems)"

0 commit comments

Comments
 (0)