@@ -185,21 +185,13 @@ sealed abstract class CaptureSet extends Showable:
185
185
*/
186
186
def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = VarState .Separate ): Boolean =
187
187
188
- /** Like `refs.exists(p)`, but testing fresh cap instances in refs last */
189
- def existsElem (refs : SimpleIdentitySet [CaptureRef ], p : CaptureRef => Boolean ): Boolean =
190
- refs.exists:
191
- case Fresh .Cap (_) => false
192
- case elem => p(elem)
193
- ||
194
- refs.exists:
195
- case elem @ Fresh .Cap (_) => p(elem)
196
- case elem => false
197
-
198
188
def debugInfo (using Context ) = i " $this accountsFor $x, which has capture set ${x.captureSetOfInfo}"
199
189
200
190
def test (using Context ) = reporting.trace(debugInfo):
201
- existsElem(elems, _.subsumes(x))
202
- || ! x.isMaxCapability
191
+ elems.exists(_.subsumes(x))
192
+ || // Even though subsumes already follows captureSetOfInfo, this is not enough.
193
+ // For instance x: C^{y, z}. Then neither y nor z subsumes x but {y, z} accounts for x.
194
+ ! x.isMaxCapability
203
195
&& ! x.derivesFrom(defn.Caps_CapSet )
204
196
&& ! (vs == VarState .Separate && x.captureSetOfInfo.containsRootCapability)
205
197
// in VarState.Separate, don't try to widen to cap since that might succeed with {cap} <: {cap}
@@ -244,7 +236,7 @@ sealed abstract class CaptureSet extends Showable:
244
236
subCaptures(that)(using ctx, vs)
245
237
246
238
/** The subcapturing test, using a given VarState */
247
- def subCaptures (that : CaptureSet )(using ctx : Context , vs : VarState = VarState ()): CompareResult =
239
+ final def subCaptures (that : CaptureSet )(using ctx : Context , vs : VarState = VarState ()): CompareResult =
248
240
val result = that.tryInclude(elems, this )
249
241
if result.isOK then
250
242
addDependent(that)
@@ -543,7 +535,7 @@ object CaptureSet:
543
535
deps = state.deps(this )
544
536
545
537
final def addThisElem (elem : CaptureRef )(using Context , VarState ): CompareResult =
546
- if isConst || ! recordElemsState() then // Fail if variable is solved or given VarState is frozen
538
+ if isConst || ! recordElemsState() then // Fail if variable is solved or given VarState is frozen
547
539
addHiddenElem(elem)
548
540
else if Existential .isBadExistential(elem) then // Fail if `elem` is an out-of-scope existential
549
541
CompareResult .Fail (this :: Nil )
@@ -1210,13 +1202,15 @@ object CaptureSet:
1210
1202
tp.captureSet
1211
1203
case tp : TermParamRef =>
1212
1204
tp.captureSet
1213
- case _ : TypeRef =>
1214
- empty
1215
- case _ : TypeParamRef =>
1216
- empty
1205
+ case tp : (TypeRef | TypeParamRef ) =>
1206
+ if tp.derivesFrom(defn.Caps_CapSet ) then tp.captureSet
1207
+ else empty
1217
1208
case CapturingType (parent, refs) =>
1218
1209
recur(parent) ++ refs
1219
1210
case tp @ AnnotatedType (parent, ann) if ann.hasSymbol(defn.ReachCapabilityAnnot ) =>
1211
+ // Note: we don't use the `ReachCapability(parent)` extractor here since that
1212
+ // only works if `parent` is a CaptureRef, but in illegal programs it might not be.
1213
+ // And then we do not want to fall back to empty.
1220
1214
parent match
1221
1215
case parent : SingletonCaptureRef if parent.isTrackableRef =>
1222
1216
tp.singletonCaptureSet
0 commit comments