@@ -674,7 +674,29 @@ class CheckCaptures extends Recheck, SymTransformer:
674
674
i " Sealed type variable $pname" , " be instantiated to" ,
675
675
i " This is often caused by a local capability $where\n leaking as part of its result. " ,
676
676
tree.srcPos)
677
- handleCall(meth, tree, () => Existential .toCap(super .recheckTypeApply(tree, pt)))
677
+ val res = handleCall(meth, tree, () => Existential .toCap(super .recheckTypeApply(tree, pt)))
678
+ if meth == defn.Caps_containsImpl then checkContains(tree)
679
+ res
680
+ end recheckTypeApply
681
+
682
+ /** Faced with a tree of form `caps.contansImpl[CS, r.type]`, check that `R` is a tracked
683
+ * capability and assert that `{r} <:CS`.
684
+ */
685
+ def checkContains (tree : TypeApply )(using Context ): Unit =
686
+ tree.fun.knownType.widen match
687
+ case fntpe : PolyType =>
688
+ tree.args match
689
+ case csArg :: refArg :: Nil =>
690
+ val cs = csArg.knownType.captureSet
691
+ val ref = refArg.knownType
692
+ capt.println(i " check contains $cs , $ref" )
693
+ ref match
694
+ case ref : CaptureRef if ref.isTracked =>
695
+ checkElem(ref, cs, tree.srcPos)
696
+ case _ =>
697
+ report.error(em " $refArg is not a tracked capability " , refArg.srcPos)
698
+ case _ =>
699
+ case _ =>
678
700
679
701
override def recheckBlock (tree : Block , pt : Type )(using Context ): Type =
680
702
inNestedLevel(super .recheckBlock(tree, pt))
0 commit comments