@@ -178,12 +178,7 @@ sealed abstract class CaptureSet extends Showable:
178
178
179
179
/** Try to include all element in `refs` to this capture set. */
180
180
protected final def tryInclude (newElems : Refs , origin : CaptureSet )(using Context , VarState ): Boolean =
181
- TypeComparer .inNestedLevel:
182
- // Run in nested level so that a error notes for a failure here can be
183
- // cancelled in case the whole comparison succeeds.
184
- // We do this here because all nested tryInclude and subCaptures calls go
185
- // through this method.
186
- newElems.forall(tryInclude(_, origin))
181
+ newElems.forall(tryInclude(_, origin))
187
182
188
183
protected def mutableToReader (origin : CaptureSet )(using Context ): Boolean =
189
184
if mutability == Mutable then toReader() else true
@@ -284,16 +279,14 @@ sealed abstract class CaptureSet extends Showable:
284
279
285
280
/** The subcapturing test, using a given VarState */
286
281
final def subCaptures (that : CaptureSet )(using ctx : Context , vs : VarState = VarState ()): Boolean =
287
- val this1 = this .adaptMutability(that)
288
- if this1 == null then false
289
- else if this1 ne this then
290
- capt.println(i " WIDEN ro $this with ${this .mutability} <:< $that with ${that.mutability} to $this1" )
291
- this1.subCaptures(that, vs)
292
- else if that.tryInclude(elems, this ) then
293
- addDependent(that)
294
- else
295
- varState.rollBack()
296
- false
282
+ TypeComparer .inNestedLevel:
283
+ val this1 = this .adaptMutability(that)
284
+ if this1 == null then false
285
+ else if this1 ne this then
286
+ capt.println(i " WIDEN ro $this with ${this .mutability} <:< $that with ${that.mutability} to $this1" )
287
+ this1.subCaptures(that, vs)
288
+ else
289
+ that.tryInclude(elems, this ) && addDependent(that)
297
290
298
291
/** Two capture sets are considered =:= equal if they mutually subcapture each other
299
292
* in a frozen state.
@@ -662,30 +655,6 @@ object CaptureSet:
662
655
663
656
var description : String = " "
664
657
665
- /** Record current elements in given VarState provided it does not yet
666
- * contain an entry for this variable.
667
- */
668
- private def recordElemsState ()(using VarState ): Boolean =
669
- varState.getElems(this ) match
670
- case None => varState.putElems(this , elems)
671
- case _ => true
672
-
673
- /** Record current dependent sets in given VarState provided it does not yet
674
- * contain an entry for this variable.
675
- */
676
- private [CaptureSet ] def recordDepsState ()(using VarState ): Boolean =
677
- varState.getDeps(this ) match
678
- case None => varState.putDeps(this , deps)
679
- case _ => true
680
-
681
- /** Reset elements to what was recorded in `state` */
682
- def resetElems ()(using state : VarState ): Unit =
683
- elems = state.elems(this )
684
-
685
- /** Reset dependent sets to what was recorded in `state` */
686
- def resetDeps ()(using state : VarState ): Unit =
687
- deps = state.deps(this )
688
-
689
658
/** Check that all maps recorded in skippedMaps map `elem` to itself
690
659
* or something subsumed by it.
691
660
*/
@@ -695,16 +664,28 @@ object CaptureSet:
695
664
assert(elem.subsumes(elem1),
696
665
i " Skipped map ${tm.getClass} maps newly added $elem to $elem1 in $this" )
697
666
667
+ protected def includeElem (elem : Capability )(using Context ): Unit =
668
+ if ! elems.contains(elem) then
669
+ elems += elem
670
+ TypeComparer .logUndoAction: () =>
671
+ elems -= elem
672
+
673
+ def includeDep (cs : CaptureSet )(using Context ): Unit =
674
+ if ! deps.contains(cs) then
675
+ deps += cs
676
+ TypeComparer .logUndoAction: () =>
677
+ deps -= cs
678
+
698
679
final def addThisElem (elem : Capability )(using Context , VarState ): Boolean =
699
- if isConst || ! recordElemsState() then // Fail if variable is solved or given VarState is frozen
680
+ if isConst || ! varState.canRecord then // Fail if variable is solved or given VarState is frozen
700
681
addIfHiddenOrFail(elem)
701
682
else if ! levelOK(elem) then
702
683
failWith(IncludeFailure (this , elem, levelError = true )) // or `elem` is not visible at the level of the set.
703
684
else
704
685
// id == 108 then assert(false, i"trying to add $elem to $this")
705
686
assert(elem.isWellformed, elem)
706
687
assert(! this .isInstanceOf [HiddenSet ] || summon[VarState ].isSeparating, summon[VarState ])
707
- elems += elem
688
+ includeElem( elem)
708
689
if isBadRoot(rootLimit, elem) then
709
690
rootAddedHandler()
710
691
newElemAddedHandler(elem)
@@ -772,7 +753,7 @@ object CaptureSet:
772
753
(cs eq this )
773
754
|| cs.isUniversal
774
755
|| isConst
775
- || recordDepsState() && { deps += cs ; true }
756
+ || varState.canRecord && { includeDep(cs) ; true }
776
757
777
758
override def disallowRootCapability (upto : Symbol )(handler : () => Context ?=> Unit )(using Context ): this .type =
778
759
rootLimit = upto
@@ -1126,7 +1107,7 @@ object CaptureSet:
1126
1107
if alias ne this then alias.add(elem)
1127
1108
else
1128
1109
def addToElems () =
1129
- elems += elem
1110
+ includeElem( elem)
1130
1111
deps.foreach: dep =>
1131
1112
assert(dep != this )
1132
1113
vs.addHidden(dep.asInstanceOf [HiddenSet ], elem)
@@ -1142,7 +1123,7 @@ object CaptureSet:
1142
1123
deps = SimpleIdentitySet (elem.hiddenSet)
1143
1124
else
1144
1125
addToElems()
1145
- elem.hiddenSet.deps += this
1126
+ elem.hiddenSet.includeDep( this )
1146
1127
case _ =>
1147
1128
addToElems()
1148
1129
@@ -1238,41 +1219,15 @@ object CaptureSet:
1238
1219
*/
1239
1220
class VarState :
1240
1221
1241
- /** A map from captureset variables to their elements at the time of the snapshot. */
1242
- private val elemsMap : util.EqHashMap [Var , Refs ] = new util.EqHashMap
1243
-
1244
- /** A map from captureset variables to their dependent sets at the time of the snapshot. */
1245
- private val depsMap : util.EqHashMap [Var , Deps ] = new util.EqHashMap
1246
-
1247
1222
/** A map from ResultCap values to other ResultCap values. If two result values
1248
1223
* `a` and `b` are unified, then `eqResultMap(a) = b` and `eqResultMap(b) = a`.
1249
1224
*/
1250
1225
private var eqResultMap : util.SimpleIdentityMap [ResultCap , ResultCap ] = util.SimpleIdentityMap .empty
1251
1226
1252
- /** A snapshot of the `eqResultMap` value at the start of a VarState transaction */
1253
- private var eqResultSnapshot : util.SimpleIdentityMap [ResultCap , ResultCap ] | Null = null
1254
-
1255
- /** The recorded elements of `v` (it's required that a recording was made) */
1256
- def elems (v : Var ): Refs = elemsMap(v)
1257
-
1258
- /** Optionally the recorded elements of `v`, None if nothing was recorded for `v` */
1259
- def getElems (v : Var ): Option [Refs ] = elemsMap.get(v)
1260
-
1261
1227
/** Record elements, return whether this was allowed.
1262
1228
* By default, recording is allowed in regular but not in frozen states.
1263
1229
*/
1264
- def putElems (v : Var , elems : Refs ): Boolean = { elemsMap(v) = elems; true }
1265
-
1266
- /** The recorded dependent sets of `v` (it's required that a recording was made) */
1267
- def deps (v : Var ): Deps = depsMap(v)
1268
-
1269
- /** Optionally the recorded dependent sets of `v`, None if nothing was recorded for `v` */
1270
- def getDeps (v : Var ): Option [Deps ] = depsMap.get(v)
1271
-
1272
- /** Record dependent sets, return whether this was allowed.
1273
- * By default, recording is allowed in regular but not in frozen states.
1274
- */
1275
- def putDeps (v : Var , deps : Deps ): Boolean = { depsMap(v) = deps; true }
1230
+ def canRecord : Boolean = true
1276
1231
1277
1232
/** Does this state allow additions of elements to capture set variables? */
1278
1233
def isOpen = true
@@ -1283,11 +1238,6 @@ object CaptureSet:
1283
1238
* but the special state VarState.Separate overrides this.
1284
1239
*/
1285
1240
def addHidden (hidden : HiddenSet , elem : Capability )(using Context ): Boolean =
1286
- elemsMap.get(hidden) match
1287
- case None =>
1288
- elemsMap(hidden) = hidden.elems
1289
- depsMap(hidden) = hidden.deps
1290
- case _ =>
1291
1241
hidden.add(elem)(using ctx, this )
1292
1242
true
1293
1243
@@ -1311,17 +1261,13 @@ object CaptureSet:
1311
1261
&& eqResultMap(c1) == null
1312
1262
&& eqResultMap(c2) == null
1313
1263
&& {
1314
- if eqResultSnapshot == null then eqResultSnapshot = eqResultMap
1315
1264
eqResultMap = eqResultMap.updated(c1, c2).updated(c2, c1)
1265
+ TypeComparer .logUndoAction: () =>
1266
+ eqResultMap.remove(c1)
1267
+ eqResultMap.remove(c2)
1316
1268
true
1317
1269
}
1318
1270
1319
- /** Roll back global state to what was recorded in this VarState */
1320
- def rollBack (): Unit =
1321
- elemsMap.keysIterator.foreach(_.resetElems()(using this ))
1322
- depsMap.keysIterator.foreach(_.resetDeps()(using this ))
1323
- if eqResultSnapshot != null then eqResultMap = eqResultSnapshot.nn
1324
-
1325
1271
private var seen : util.EqHashSet [Capability ] = new util.EqHashSet
1326
1272
1327
1273
/** Run test `pred` unless `ref` was seen in an enclosing `ifNotSeen` operation */
@@ -1341,8 +1287,7 @@ object CaptureSet:
1341
1287
* subsume arbitary types, which are then recorded in their hidden sets.
1342
1288
*/
1343
1289
class Closed extends VarState :
1344
- override def putElems (v : Var , refs : Refs ) = false
1345
- override def putDeps (v : Var , deps : Deps ) = false
1290
+ override def canRecord = false
1346
1291
override def isOpen = false
1347
1292
override def toString = " closed varState"
1348
1293
@@ -1366,23 +1311,29 @@ object CaptureSet:
1366
1311
*/
1367
1312
def HardSeparate (using Context ): Separating = ccState.HardSeparate
1368
1313
1369
- /** A special state that turns off recording of elements. Used only
1370
- * in `addSub` to prevent cycles in recordings. Instantiated in ccState.Unrecorded.
1371
- */
1372
- class Unrecorded extends VarState :
1373
- override def putElems (v : Var , refs : Refs ) = true
1374
- override def putDeps (v : Var , deps : Deps ) = true
1375
- override def rollBack (): Unit = ()
1314
+ /** A mixin trait that overrides the addHidden and unify operations to
1315
+ * not depend in state. */
1316
+ trait Stateless extends VarState :
1317
+
1318
+ /** Allow adding hidden elements, but don't store them */
1376
1319
override def addHidden (hidden : HiddenSet , elem : Capability )(using Context ): Boolean = true
1320
+
1321
+ /** Don't allow to unify result caps */
1322
+ override def unify (c1 : ResultCap , c2 : ResultCap )(using Context ): Boolean = false
1323
+ end Stateless
1324
+
1325
+ /** An open state that turns off recording of hidden elements (but allows
1326
+ * adding them). Used in `addAsDependentTo`. Instantiated in ccState.Unrecorded.
1327
+ */
1328
+ class Unrecorded extends VarState , Stateless :
1377
1329
override def toString = " unrecorded varState"
1378
1330
1379
1331
def Unrecorded (using Context ): Unrecorded = ccState.Unrecorded
1380
1332
1381
1333
/** A closed state that turns off recording of hidden elements (but allows
1382
1334
* adding them). Used in `mightAccountFor`. Instantiated in ccState.ClosedUnrecorded.
1383
1335
*/
1384
- class ClosedUnrecorded extends Closed :
1385
- override def addHidden (hidden : HiddenSet , elem : Capability )(using Context ): Boolean = true
1336
+ class ClosedUnrecorded extends Closed , Stateless :
1386
1337
override def toString = " closed unrecorded varState"
1387
1338
1388
1339
def ClosedUnrecorded (using Context ): ClosedUnrecorded = ccState.ClosedUnrecorded
0 commit comments