@@ -147,7 +147,7 @@ sealed abstract class CaptureSet extends Showable:
147147 * capture set.
148148 */
149149 protected final def addNewElem (elem : CaptureRef )(using ctx : Context , vs : VarState ): CompareResult =
150- if elem.isMaxCapability || vs.frozen != Frozen . None then
150+ if elem.isMaxCapability || ! vs.isOpen then
151151 addThisElem(elem)
152152 else
153153 addThisElem(elem).orElse:
@@ -168,7 +168,7 @@ sealed abstract class CaptureSet extends Showable:
168168 protected def addThisElem (elem : CaptureRef )(using Context , VarState ): CompareResult
169169
170170 protected def addHiddenElem (elem : CaptureRef )(using ctx : Context , vs : VarState ): CompareResult =
171- if elems.exists(_.maxSubsumes(elem, canAddHidden = vs.frozen != Frozen . All ))
171+ if elems.exists(_.maxSubsumes(elem, canAddHidden = true ))
172172 then CompareResult .OK
173173 else CompareResult .Fail (this :: Nil )
174174
@@ -177,13 +177,13 @@ sealed abstract class CaptureSet extends Showable:
177177
178178 /** If `cs` is a variable, add this capture set as one of its dependent sets */
179179 protected def addAsDependentTo (cs : CaptureSet )(using Context ): this .type =
180- cs.addDependent(this )(using ctx, UnrecordedState )
180+ cs.addDependent(this )(using ctx, VarState . Unrecorded )
181181 this
182182
183183 /** {x} <:< this where <:< is subcapturing, but treating all variables
184184 * as frozen.
185185 */
186- def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = FrozenAllState ): Boolean =
186+ def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = VarState . Separate ): Boolean =
187187
188188 /** Like `refs.exists(p)`, but testing fresh cap instances in refs last */
189189 def existsElem (refs : SimpleIdentitySet [CaptureRef ], p : CaptureRef => Boolean ): Boolean =
@@ -201,9 +201,9 @@ sealed abstract class CaptureSet extends Showable:
201201 existsElem(elems, _.subsumes(x))
202202 || ! x.isMaxCapability
203203 && ! x.derivesFrom(defn.Caps_CapSet )
204- && ! (vs.frozen == Frozen . All && x.captureSetOfInfo.containsRootCapability)
205- // under Frozen.All , don't try to widen to cap since that might succeed with {cap} <: {cap}
206- && x.captureSetOfInfo.subCaptures(this , Frozen . All ).isOK
204+ && ! (vs == VarState . Separate && x.captureSetOfInfo.containsRootCapability)
205+ // in VarState.Separate , don't try to widen to cap since that might succeed with {cap} <: {cap}
206+ && x.captureSetOfInfo.subCaptures(this , VarState . Separate ).isOK
207207
208208 comparer match
209209 case comparer : ExplainingTypeComparer => comparer.traceIndented(debugInfo)(test)
@@ -219,7 +219,7 @@ sealed abstract class CaptureSet extends Showable:
219219 */
220220 def mightAccountFor (x : CaptureRef )(using Context ): Boolean =
221221 reporting.trace(i " $this mightAccountFor $x, ${x.captureSetOfInfo}? " , show = true ):
222- elems.exists(_.subsumes(x)(using ctx, FrozenUnrecordedHiddenState ))
222+ elems.exists(_.subsumes(x)(using ctx, VarState . ClosedUnrecorded ))
223223 || ! x.isMaxCapability
224224 && {
225225 val elems = x.captureSetOfInfo.elems
@@ -240,15 +240,11 @@ sealed abstract class CaptureSet extends Showable:
240240 * be added when making this test. An attempt to add either
241241 * will result in failure.
242242 */
243- final def subCaptures (that : CaptureSet , frozen : Frozen )(using Context ): CompareResult =
244- val state = frozen match
245- case Frozen .None => VarState ()
246- case Frozen .Vars => FrozenVarState ()
247- case Frozen .All => FrozenAllState
248- subCaptures(that)(using ctx, state)
243+ final def subCaptures (that : CaptureSet , vs : VarState )(using Context ): CompareResult =
244+ subCaptures(that)(using ctx, vs)
249245
250246 /** The subcapturing test, using a given VarState */
251- private def subCaptures (that : CaptureSet )(using Context , VarState ): CompareResult =
247+ def subCaptures (that : CaptureSet )(using ctx : Context , vs : VarState = VarState () ): CompareResult =
252248 val result = that.tryInclude(elems, this )
253249 if result.isOK then
254250 addDependent(that)
@@ -262,16 +258,16 @@ sealed abstract class CaptureSet extends Showable:
262258 * in a frozen state.
263259 */
264260 def =:= (that : CaptureSet )(using Context ): Boolean =
265- this .subCaptures(that, Frozen . All ).isOK
266- && that.subCaptures(this , Frozen . All ).isOK
261+ this .subCaptures(that, VarState . Separate ).isOK
262+ && that.subCaptures(this , VarState . Separate ).isOK
267263
268264 /** The smallest capture set (via <:<) that is a superset of both
269265 * `this` and `that`
270266 */
271267 def ++ (that : CaptureSet )(using Context ): CaptureSet =
272- if this .subCaptures(that, Frozen . All ).isOK then
268+ if this .subCaptures(that, VarState . Separate ).isOK then
273269 if that.isAlwaysEmpty && this .keepAlways then this else that
274- else if that.subCaptures(this , Frozen . All ).isOK then this
270+ else if that.subCaptures(this , VarState . Separate ).isOK then this
275271 else if this .isConst && that.isConst then Const (this .elems ++ that.elems)
276272 else Union (this , that)
277273
@@ -286,8 +282,8 @@ sealed abstract class CaptureSet extends Showable:
286282 /** The largest capture set (via <:<) that is a subset of both `this` and `that`
287283 */
288284 def ** (that : CaptureSet )(using Context ): CaptureSet =
289- if this .subCaptures(that, Frozen . Vars ).isOK then this
290- else if that.subCaptures(this , Frozen . Vars ).isOK then that
285+ if this .subCaptures(that, VarState . Closed () ).isOK then this
286+ else if that.subCaptures(this , VarState . Closed () ).isOK then that
291287 else if this .isConst && that.isConst then Const (elemIntersection(this , that))
292288 else Intersection (this , that)
293289
@@ -556,7 +552,7 @@ object CaptureSet:
556552 else
557553 // id == 108 then assert(false, i"trying to add $elem to $this")
558554 assert(elem.isTrackableRef, elem)
559- assert(! this .isInstanceOf [HiddenSet ] || summon[VarState ] == FrozenAllState , summon[VarState ])
555+ assert(! this .isInstanceOf [HiddenSet ] || summon[VarState ] == VarState . Separate , summon[VarState ])
560556 elems += elem
561557 if elem.isRootCapability then
562558 rootAddedHandler()
@@ -652,7 +648,8 @@ object CaptureSet:
652648 .showing(i " solve $this = $result" , capt)
653649 // println(i"solving var $this $approx ${approx.isConst} deps = ${deps.toList}")
654650 val newElems = approx.elems -- elems
655- if tryInclude(newElems, empty)(using ctx, VarState ()).isOK then
651+ given VarState ()
652+ if tryInclude(newElems, empty).isOK then
656653 markSolved()
657654
658655 /** Mark set as solved and propagate this info to all dependent sets */
@@ -939,10 +936,6 @@ object CaptureSet:
939936 /** A capture set variable used to record the references hidden by a Fresh.Cap instance */
940937 class HiddenSet (initialHidden : Refs = emptySet)(using @ constructorOnly ictx : Context )
941938 extends Var (initialElems = initialHidden):
942- override def recordElemsState ()(using VarState ): Boolean =
943- varState.getElems(this ) match
944- case None => varState.putHidden(this , elems)
945- case _ => true
946939
947940 /** Apply function `f` to `elems` while setting `elems` to empty for the
948941 * duration. This is used to escape infinite recursions if two Frash.Caps
@@ -990,7 +983,7 @@ object CaptureSet:
990983 */
991984 def subCapturesRange (arg1 : TypeBounds , arg2 : Type )(using Context ): Boolean = arg1 match
992985 case TypeBounds (CapturingType (lo, loRefs), CapturingType (hi, hiRefs)) if lo =:= hi =>
993- given VarState = VarState ()
986+ given VarState ()
994987 val cs2 = arg2.captureSet
995988 hiRefs.subCaptures(cs2).isOK && cs2.subCaptures(loRefs).isOK
996989 case _ =>
@@ -1048,19 +1041,11 @@ object CaptureSet:
10481041 case _ => this
10491042 end CompareResult
10501043
1051- /** An enum indicating a Frozen degree for subCapturing tests */
1052- enum Frozen :
1053- case None // operations are performed in a regular VarState
1054- case Vars // operations are performed in a FrozenVarState
1055- case All // operations are performed in FrozenAllState
1056-
10571044 /** A VarState serves as a snapshot mechanism that can undo
10581045 * additions of elements or super sets if an operation fails
10591046 */
10601047 class VarState :
10611048
1062- def frozen : Frozen = Frozen .None
1063-
10641049 /** A map from captureset variables to their elements at the time of the snapshot. */
10651050 protected val elemsMap : util.EqHashMap [Var , Refs ] = new util.EqHashMap
10661051
@@ -1089,11 +1074,19 @@ object CaptureSet:
10891074 */
10901075 def putDeps (v : Var , deps : Deps ): Boolean = { depsMap(v) = deps; true }
10911076
1092- /** Record hidden elements in elemsMap of hidden set `v`,
1077+ /** Does this state allow additions of elements to capture set variables? */
1078+ def isOpen = true
1079+
1080+ /** Add element to hidden set, recording it in elemsMap,
10931081 * return whether this was allowed. By default, recording is allowed
1094- * but the special state FrozenAllState overrides this.
1082+ * but the special state VarState.Separate overrides this.
10951083 */
1096- def putHidden (v : HiddenSet , elems : Refs ): Boolean = { elemsMap(v) = elems; true }
1084+ def addHidden (hidden : HiddenSet , elem : CaptureRef ): Boolean =
1085+ elemsMap.get(hidden) match
1086+ case None => elemsMap(hidden) = hidden.elems
1087+ case _ =>
1088+ hidden.elems += elem
1089+ true
10971090
10981091 /** Roll back global state to what was recorded in this VarState */
10991092 def rollBack (): Unit =
@@ -1107,45 +1100,48 @@ object CaptureSet:
11071100 if seen.add(ref) then
11081101 try pred finally seen -= ref
11091102 else false
1110- end VarState
11111103
1112- /** A class for states that do not allow to record elements or dependent sets.
1113- * In effect this means that no new elements or dependent sets can be added
1114- * in these states (since the previous state cannot be recorded in a snapshot)
1115- * On the other hand, these states do allow by default Fresh.Cap instances to
1116- * subsume arbitary types, which are then recorded in their hidden sets.
1117- */
1118- class FrozenVarState extends VarState :
1119- override def frozen = Frozen .Vars
1120- override def putElems (v : Var , refs : Refs ) = false
1121- override def putDeps (v : Var , deps : Deps ) = false
1122- override def putHidden (v : HiddenSet , elems : Refs ): Boolean = { elemsMap(v) = elems; true }
1104+ object VarState :
11231105
1124- @ sharable
1125- /** A frozen state that allows a Fresh.Cap instancce to subsume a
1126- * reference `r` only if `r` is already present in the hidden set of the instance.
1127- * No new references can be added.
1128- */
1129- object FrozenAllState extends FrozenVarState :
1130- override def frozen = Frozen .All
1131- override def putHidden (v : HiddenSet , elems : Refs ): Boolean = false
1106+ /** A class for states that do not allow to record elements or dependent sets.
1107+ * In effect this means that no new elements or dependent sets can be added
1108+ * in these states (since the previous state cannot be recorded in a snapshot)
1109+ * On the other hand, these states do allow by default Fresh.Cap instances to
1110+ * subsume arbitary types, which are then recorded in their hidden sets.
1111+ */
1112+ class Closed extends VarState :
1113+ override def putElems (v : Var , refs : Refs ) = false
1114+ override def putDeps (v : Var , deps : Deps ) = false
1115+ override def isOpen = false
1116+
1117+ /** A closed state that allows a Fresh.Cap instance to subsume a
1118+ * reference `r` only if `r` is already present in the hidden set of the instance.
1119+ * No new references can be added.
1120+ */
1121+ @ sharable
1122+ object Separate extends Closed :
1123+ override def addHidden (hidden : HiddenSet , elem : CaptureRef ): Boolean = false
11321124
1133- @ sharable
1134- /** A frozen state that allows a Fresh.Cap instancce to subsume a
1135- * reference `r` only if `r` is already present in the hidden set of the instance.
1136- * No new references can be added.
1137- */
1138- object FrozenUnrecordedHiddenState extends FrozenVarState
1125+ /** A special state that turns off recording of elements. Used only
1126+ * in `addSub` to prevent cycles in recordings.
1127+ */
1128+ @ sharable
1129+ private [CaptureSet ] object Unrecorded extends VarState :
1130+ override def putElems (v : Var , refs : Refs ) = true
1131+ override def putDeps (v : Var , deps : Deps ) = true
1132+ override def rollBack (): Unit = ()
1133+ override def addHidden (hidden : HiddenSet , elem : CaptureRef ): Boolean = true
1134+
1135+ /** A closed state that turns off recording of hidden elements (but allows
1136+ * adding them). Used in `mightAccountFor`.
1137+ */
1138+ @ sharable
1139+ private [CaptureSet ] object ClosedUnrecorded extends Closed :
1140+ override def addHidden (hidden : HiddenSet , elem : CaptureRef ): Boolean = true
11391141
1140- @ sharable
1141- /** A special state that turns off recording of elements. Used only
1142- * in `addSub` to prevent cycles in recordings.
1143- */
1144- private object UnrecordedState extends VarState :
1145- override def putElems (v : Var , refs : Refs ) = true
1146- override def putDeps (v : Var , deps : Deps ) = true
1147- override def rollBack (): Unit = ()
1142+ end VarState
11481143
1144+ @ sharable
11491145 /** The current VarState, as passed by the implicit context */
11501146 def varState (using state : VarState ): VarState = state
11511147
0 commit comments