@@ -142,7 +142,7 @@ sealed abstract class CaptureSet extends Showable:
142
142
* capture set.
143
143
*/
144
144
protected final def addNewElem (elem : CaptureRef )(using Context , VarState ): CompareResult =
145
- if elem.isMaxCapability || summon[VarState ].isInstanceOf [FrozenState ] then
145
+ if elem.isMaxCapability || summon[VarState ].isInstanceOf [FrozenVarState ] then
146
146
addThisElem(elem)
147
147
else
148
148
addThisElem(elem).orElse:
@@ -173,7 +173,7 @@ sealed abstract class CaptureSet extends Showable:
173
173
/** {x} <:< this where <:< is subcapturing, but treating all variables
174
174
* as frozen.
175
175
*/
176
- def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = FrozenSepState ): Boolean =
176
+ def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = FrozenAllState ): Boolean =
177
177
178
178
/** Like `refs.exists(p)`, but testing fresh cap instances in refs last */
179
179
def existsElem (refs : SimpleIdentitySet [CaptureRef ], p : CaptureRef => Boolean ): Boolean =
@@ -191,7 +191,10 @@ sealed abstract class CaptureSet extends Showable:
191
191
existsElem(elems, _.subsumes(x))
192
192
|| ! x.isMaxCapability
193
193
&& ! x.derivesFrom(defn.Caps_CapSet )
194
- && x.captureSetOfInfo.subCaptures(this , frozen = true ).isOK
194
+ && x.captureSetOfInfo.subCaptures(this )(using ctx,
195
+ vs match
196
+ case vs : FrozenVarState => vs
197
+ case _ => FrozenVarState ()).isOK
195
198
196
199
comparer match
197
200
case comparer : ExplainingTypeComparer => comparer.traceIndented(debugInfo)(test)
@@ -207,7 +210,7 @@ sealed abstract class CaptureSet extends Showable:
207
210
*/
208
211
def mightAccountFor (x : CaptureRef )(using Context ): Boolean =
209
212
reporting.trace(i " $this mightAccountFor $x, ${x.captureSetOfInfo}? " , show = true ):
210
- elems.exists(_.subsumes(x)(using ctx, FrozenState ()))
213
+ elems.exists(_.subsumes(x)(using ctx, FrozenVarState ()))
211
214
|| ! x.isMaxCapability
212
215
&& {
213
216
val elems = x.captureSetOfInfo.elems
@@ -228,8 +231,12 @@ sealed abstract class CaptureSet extends Showable:
228
231
* be added when making this test. An attempt to add either
229
232
* will result in failure.
230
233
*/
231
- final def subCaptures (that : CaptureSet , frozen : Boolean )(using Context ): CompareResult =
232
- subCaptures(that)(using ctx, if frozen then FrozenState () else VarState ())
234
+ final def subCaptures (that : CaptureSet , frozen : Frozen )(using Context ): CompareResult =
235
+ val state = frozen match
236
+ case Frozen .None => VarState ()
237
+ case Frozen .Vars => FrozenVarState ()
238
+ case Frozen .All => FrozenAllState
239
+ subCaptures(that)(using ctx, state)
233
240
234
241
/** The subcapturing test, using a given VarState */
235
242
private def subCaptures (that : CaptureSet )(using Context , VarState ): CompareResult =
@@ -246,16 +253,16 @@ sealed abstract class CaptureSet extends Showable:
246
253
* in a frozen state.
247
254
*/
248
255
def =:= (that : CaptureSet )(using Context ): Boolean =
249
- this .subCaptures(that, frozen = true ).isOK
250
- && that.subCaptures(this , frozen = true ).isOK
256
+ this .subCaptures(that, Frozen . All ).isOK
257
+ && that.subCaptures(this , Frozen . All ).isOK
251
258
252
259
/** The smallest capture set (via <:<) that is a superset of both
253
260
* `this` and `that`
254
261
*/
255
262
def ++ (that : CaptureSet )(using Context ): CaptureSet =
256
- if this .subCaptures(that, frozen = true ).isOK then
263
+ if this .subCaptures(that, Frozen . All ).isOK then
257
264
if that.isAlwaysEmpty && this .keepAlways then this else that
258
- else if that.subCaptures(this , frozen = true ).isOK then this
265
+ else if that.subCaptures(this , Frozen . All ).isOK then this
259
266
else if this .isConst && that.isConst then Const (this .elems ++ that.elems)
260
267
else Union (this , that)
261
268
@@ -267,8 +274,8 @@ sealed abstract class CaptureSet extends Showable:
267
274
/** The largest capture set (via <:<) that is a subset of both `this` and `that`
268
275
*/
269
276
def ** (that : CaptureSet )(using Context ): CaptureSet =
270
- if this .subCaptures(that, frozen = true ).isOK then this
271
- else if that.subCaptures(this , frozen = true ).isOK then that
277
+ if this .subCaptures(that, Frozen . Vars ).isOK then this
278
+ else if that.subCaptures(this , Frozen . Vars ).isOK then that
272
279
else if this .isConst && that.isConst then Const (elemIntersection(this , that))
273
280
else Intersection (this , that)
274
281
@@ -395,6 +402,12 @@ object CaptureSet:
395
402
type Vars = SimpleIdentitySet [Var ]
396
403
type Deps = SimpleIdentitySet [CaptureSet ]
397
404
405
+ /** An enum indicating a Frozen degree for subCapturing tests */
406
+ enum Frozen :
407
+ case None // operations are performed in a regular VarState
408
+ case Vars // operations are performed in a FrozenVarState
409
+ case All // operations are performed in FrozenAllState
410
+
398
411
@ sharable private var varId = 0
399
412
400
413
/** If set to `true`, capture stack traces that tell us where sets are created */
@@ -538,7 +551,7 @@ object CaptureSet:
538
551
else
539
552
// if id == 34 then assert(!elem.isUniversalRootCapability)
540
553
assert(elem.isTrackableRef, elem)
541
- assert(! this .isInstanceOf [HiddenSet ] || summon[VarState ] == FrozenSepState , summon[VarState ])
554
+ assert(! this .isInstanceOf [HiddenSet ] || summon[VarState ] == FrozenAllState , summon[VarState ])
542
555
elems += elem
543
556
if elem.isRootCapability then
544
557
rootAddedHandler()
@@ -1043,7 +1056,7 @@ object CaptureSet:
1043
1056
def getElems (v : Var ): Option [Refs ] = elemsMap.get(v)
1044
1057
1045
1058
/** Record elements, return whether this was allowed.
1046
- * By default, recording is allowed but the special state FrozenState
1059
+ * By default, recording is allowed in regular both not in frozen states.
1047
1060
* overrides this.
1048
1061
*/
1049
1062
def putElems (v : Var , elems : Refs ): Boolean = { elemsMap(v) = elems; true }
@@ -1055,14 +1068,14 @@ object CaptureSet:
1055
1068
def getDeps (v : Var ): Option [Deps ] = depsMap.get(v)
1056
1069
1057
1070
/** Record dependent sets, return whether this was allowed.
1058
- * By default, recording is allowed but the special state FrozenState
1071
+ * By default, recording is allowed in regular both not in frozen states.
1059
1072
* overrides this.
1060
1073
*/
1061
1074
def putDeps (v : Var , deps : Deps ): Boolean = { depsMap(v) = deps; true }
1062
1075
1063
1076
/** Record hidden elements in elemsMap of hidden set `v`,
1064
1077
* return whether this was allowed. By default, recording is allowed
1065
- * but the special state FrozenSepState overrides this.
1078
+ * but the special state FrozenAllState overrides this.
1066
1079
*/
1067
1080
def putHidden (v : HiddenSet , elems : Refs ): Boolean = { elemsMap(v) = elems; true }
1068
1081
@@ -1080,21 +1093,22 @@ object CaptureSet:
1080
1093
else false
1081
1094
end VarState
1082
1095
1083
- /** A special state that does not allow to record elements or dependent sets.
1096
+ /** A class for states that do not allow to record elements or dependent sets.
1084
1097
* In effect this means that no new elements or dependent sets can be added
1085
- * in this state (since the previous state cannot be recorded in a snapshot)
1086
- * On the other hand, this state does allow by default Fresh.Cap to subsume arbitary
1087
- * types, which are then recorded in its hidden set .
1098
+ * in these states (since the previous state cannot be recorded in a snapshot)
1099
+ * On the other hand, these states do allow by default Fresh.Cap instances to
1100
+ * subsume arbitary types, which are then recorded in their hidden sets .
1088
1101
*/
1089
- class FrozenState extends VarState :
1102
+ class FrozenVarState extends VarState :
1090
1103
override def putElems (v : Var , refs : Refs ) = false
1091
1104
override def putDeps (v : Var , deps : Deps ) = false
1092
1105
1093
1106
@ sharable
1094
- /** A frozen state that allows a Fresh.Cap instncce to subsume a
1095
- * reference `r` only if `r` is present in the hidden set of the instance.
1107
+ /** A frozen state that allows a Fresh.Cap instancce to subsume a
1108
+ * reference `r` only if `r` is already present in the hidden set of the instance.
1109
+ * No new references can be added.
1096
1110
*/
1097
- object FrozenSepState extends FrozenState :
1111
+ object FrozenAllState extends FrozenVarState :
1098
1112
override def putHidden (v : HiddenSet , elems : Refs ): Boolean = false
1099
1113
1100
1114
@ sharable
0 commit comments