@@ -185,21 +185,13 @@ sealed abstract class CaptureSet extends Showable:
185185 */
186186 def accountsFor (x : CaptureRef )(using ctx : Context , vs : VarState = VarState .Separate ): Boolean =
187187
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-
198188 def debugInfo (using Context ) = i " $this accountsFor $x, which has capture set ${x.captureSetOfInfo}"
199189
200190 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
203195 && ! x.derivesFrom(defn.Caps_CapSet )
204196 && ! (vs == VarState .Separate && x.captureSetOfInfo.containsRootCapability)
205197 // 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:
244236 subCaptures(that)(using ctx, vs)
245237
246238 /** 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 =
248240 val result = that.tryInclude(elems, this )
249241 if result.isOK then
250242 addDependent(that)
@@ -543,7 +535,7 @@ object CaptureSet:
543535 deps = state.deps(this )
544536
545537 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
547539 addHiddenElem(elem)
548540 else if Existential .isBadExistential(elem) then // Fail if `elem` is an out-of-scope existential
549541 CompareResult .Fail (this :: Nil )
@@ -1210,13 +1202,15 @@ object CaptureSet:
12101202 tp.captureSet
12111203 case tp : TermParamRef =>
12121204 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
12171208 case CapturingType (parent, refs) =>
12181209 recur(parent) ++ refs
12191210 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.
12201214 parent match
12211215 case parent : SingletonCaptureRef if parent.isTrackableRef =>
12221216 tp.singletonCaptureSet
0 commit comments