Skip to content

Commit 50f1e83

Browse files
committed
Add undo infrastructure in TypeComparer
1 parent c094431 commit 50f1e83

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
5353
needsGc = false
5454
maxErrorLevel = -1
5555
errorNotes = Nil
56+
logSize = 0
5657
if Config.checkTypeComparerReset then checkReset()
5758

5859
private var pendingSubTypes: util.MutableSet[(Type, Type)] | Null = null
@@ -62,6 +63,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
6263
private var maxErrorLevel: Int = -1
6364
protected var errorNotes: List[(Int, ErrorNote)] = Nil
6465

66+
private val undoLog = mutable.ArrayBuffer[() => Unit]()
67+
private var logSize = 0
68+
6569
private var needsGc = false
6670

6771
private var canCompareAtoms: Boolean = true // used for internal consistency checking
@@ -1579,15 +1583,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
15791583
&& tp1.derivesFrom(defn.Caps_CapSet)
15801584
&& tp2.derivesFrom(defn.Caps_CapSet)
15811585

1586+
def rollBack(prevSize: Int): Unit =
1587+
var i = prevSize
1588+
while i < undoLog.size do
1589+
undoLog(i)()
1590+
i += 1
1591+
undoLog.takeInPlace(prevSize)
1592+
15821593
// begin recur
15831594
if tp2 eq NoType then false
15841595
else if tp1 eq tp2 then true
15851596
else
15861597
val savedCstr = constraint
15871598
val savedGadt = ctx.gadt
1599+
val savedLogSize = logSize
15881600
inline def restore() =
15891601
state.constraint = savedCstr
15901602
ctx.gadtState.restore(savedGadt)
1603+
if undoLog.size != savedLogSize then
1604+
rollBack(savedLogSize)
15911605
val savedSuccessCount = successCount
15921606
try
15931607
val result = inNestedLevel:
@@ -2885,6 +2899,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28852899
(tp1.isBoxedCapturing == tp2.isBoxedCapturing)
28862900
|| refs1.subCaptures(CaptureSet.empty, makeVarState())
28872901

2902+
protected def logUndoAction(action: () => Unit) =
2903+
undoLog += action
2904+
28882905
// ----------- Diagnostics --------------------------------------------------
28892906

28902907
/** A hook for showing subtype traces. Overridden in ExplainingTypeComparer */
@@ -3504,6 +3521,9 @@ object TypeComparer {
35043521
def subCaptures(refs1: CaptureSet, refs2: CaptureSet, vs: CaptureSet.VarState)(using Context): Boolean =
35053522
comparing(_.subCaptures(refs1, refs2, vs))
35063523

3524+
def logUndoAction(action: () => Unit)(using Context): Unit =
3525+
comparer.logUndoAction(action)
3526+
35073527
def inNestedLevel(op: => Boolean)(using Context): Boolean =
35083528
comparer.inNestedLevel(op)
35093529

0 commit comments

Comments
 (0)