@@ -86,15 +86,24 @@ extension (tree: Tree)
8686 case Apply (TypeApply (_, refs :: Nil ), _) => refs.tpe
8787 case _ =>
8888 if tree.symbol.maybeOwner == defn.RetainsCapAnnot
89- then ref( defn.captureRoot) else NoType
89+ then defn.captureRoot.termRef else NoType
9090
9191extension (tp : Type )
9292
93- def retainedElementsRaw (using Context ): List [Type ] = tp match
93+ def toCapabilities (using Context ): List [Capability ] = tp match
9494 case ReachCapability (tp1) =>
95- tp1.reach :: Nil
95+ tp1.toCapabilities.map(_. reach)
9696 case ReadOnlyCapability (tp1) =>
97- tp1.readOnly :: Nil
97+ tp1.toCapabilities.map(_.readOnly)
98+ case ref : TermRef if ref.isCapRef =>
99+ GlobalCap :: Nil
100+ case ref : Capability if ref.isTrackableRef =>
101+ ref :: Nil
102+ case _ =>
103+ // if this was compiled from cc syntax, problem should have been reported at Typer
104+ throw IllegalCaptureRef (tp)
105+
106+ def retainedElementsRaw (using Context ): List [Type ] = tp match
98107 case OrType (tp1, tp2) =>
99108 tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
100109 case tp =>
@@ -103,9 +112,7 @@ extension (tp: Type)
103112 else tp :: Nil // should be checked by wellformedness
104113
105114 def retainedElements (using Context ): List [Capability ] =
106- retainedElementsRaw.map:
107- case tp : CaptureRef => tp
108- case tp => throw IllegalCaptureRef (tp)
115+ retainedElementsRaw.flatMap(_.toCapabilities)
109116
110117 /** Is this type a Capability that can be tracked?
111118 * This is true for
@@ -539,57 +546,25 @@ class CleanupRetains(using Context) extends TypeMap:
539546 RetainingType (tp, defn.NothingType , byName = annot.symbol == defn.RetainsByNameAnnot )
540547 case _ => mapOver(tp)
541548
542- // /** An extractor for `caps.reachCapability(ref)`, which is used to express a reach
543- // * capability as a tree in a @retains annotation.
544- // */
545- // object ReachCapabilityApply:
546- // def unapply(tree: Apply)(using Context): Option[Tree] = tree match
547- // case Apply(reach, arg :: Nil) if reach.symbol == defn.Caps_reachCapability => Some(arg)
548- // case _ => None
549-
550- // /** An extractor for `caps.readOnlyCapability(ref)`, which is used to express a read-only
551- // * capability as a tree in a @retains annotation.
552- // */
553- // object ReadOnlyCapabilityApply:
554- // def unapply(tree: Apply)(using Context): Option[Tree] = tree match
555- // case Apply(ro, arg :: Nil) if ro.symbol == defn.Caps_readOnlyCapability => Some(arg)
556- // case _ => None
557-
558549abstract class AnnotatedCapability (annotCls : Context ?=> ClassSymbol ):
559550 def apply (tp : Type )(using Context ): AnnotatedType =
560- assert(tp.isTrackableRef, i " not a trackable ref: $tp" )
561- tp match
562- case AnnotatedType (_, annot) =>
563- assert(! unwrappable.contains(annot.symbol), i " illegal combination of derived capabilities: $annotCls over ${annot.symbol}" )
564- case _ =>
565- tp match
566- case tp : Capability => tp.derivedRef(annotCls)
567- case _ => AnnotatedType (tp, Annotation (annotCls, util.Spans .NoSpan ))
551+ AnnotatedType (tp, Annotation (annotCls, util.Spans .NoSpan ))
568552
569- def unapply (tree : AnnotatedType )(using Context ): Option [Capability ] = tree match
570- case AnnotatedType (parent : Capability , ann) if ann.hasSymbol(annotCls) => Some (parent)
553+ def unapply (tree : AnnotatedType )(using Context ): Option [Type ] = tree match
554+ case AnnotatedType (parent : Type , ann) if ann.hasSymbol(annotCls) => Some (parent)
571555 case _ => None
572556
573- protected def unwrappable (using Context ): Set [Symbol ]
574557end AnnotatedCapability
575558
576- object QualifiedCapability :
577- def unapply (tree : AnnotatedType )(using Context ): Option [Capability ] = tree match
578- case AnnotatedType (parent : Capability , ann)
579- if defn.capabilityQualifierAnnots.contains(ann.symbol) => Some (parent)
580- case _ => None
581-
582559/** An extractor for `ref @readOnlyCapability`, which is used to express
583560 * the read-only capability `ref.rd` as a type.
584561 */
585- object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot ):
586- protected def unwrappable (using Context ) = Set ()
562+ object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot )
587563
588564/** An extractor for `ref @annotation.internal.reachCapability`, which is used to express
589565 * the reach capability `ref*` as a type.
590566 */
591- object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot ):
592- protected def unwrappable (using Context ) = Set (defn.ReadOnlyCapabilityAnnot )
567+ object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot )
593568
594569/** An extractor for all kinds of function types as well as method and poly types.
595570 * It includes aliases of function types such as `=>`. TODO: Can we do without?
0 commit comments