@@ -89,15 +89,24 @@ extension (tree: Tree)
8989 case Apply (TypeApply (_, refs :: Nil ), _) => refs.tpe
9090 case _ =>
9191 if tree.symbol.maybeOwner == defn.RetainsCapAnnot
92- then ref( defn.captureRoot) else NoType
92+ then defn.captureRoot.termRef else NoType
9393
9494extension (tp : Type )
9595
96- def retainedElementsRaw (using Context ): List [Type ] = tp match
96+ def toCapabilities (using Context ): List [Capability ] = tp match
9797 case ReachCapability (tp1) =>
98- tp1.reach :: Nil
98+ tp1.toCapabilities.map(_. reach)
9999 case ReadOnlyCapability (tp1) =>
100- tp1.readOnly :: Nil
100+ tp1.toCapabilities.map(_.readOnly)
101+ case ref : TermRef if ref.isCapRef =>
102+ GlobalCap :: Nil
103+ case ref : Capability if ref.isTrackableRef =>
104+ ref :: Nil
105+ case _ =>
106+ // if this was compiled from cc syntax, problem should have been reported at Typer
107+ throw IllegalCaptureRef (tp)
108+
109+ def retainedElementsRaw (using Context ): List [Type ] = tp match
101110 case OrType (tp1, tp2) =>
102111 tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
103112 case tp =>
@@ -106,9 +115,7 @@ extension (tp: Type)
106115 else tp :: Nil // should be checked by wellformedness
107116
108117 def retainedElements (using Context ): List [Capability ] =
109- retainedElementsRaw.map:
110- case tp : CaptureRef => tp
111- case tp => throw IllegalCaptureRef (tp)
118+ retainedElementsRaw.flatMap(_.toCapabilities)
112119
113120 /** Is this type a Capability that can be tracked?
114121 * This is true for
@@ -562,57 +569,25 @@ trait FollowAliasesMap(using Context) extends TypeMap:
562569 else t
563570 else mapOver(t)
564571
565- // /** An extractor for `caps.reachCapability(ref)`, which is used to express a reach
566- // * capability as a tree in a @retains annotation.
567- // */
568- // object ReachCapabilityApply:
569- // def unapply(tree: Apply)(using Context): Option[Tree] = tree match
570- // case Apply(reach, arg :: Nil) if reach.symbol == defn.Caps_reachCapability => Some(arg)
571- // case _ => None
572-
573- // /** An extractor for `caps.readOnlyCapability(ref)`, which is used to express a read-only
574- // * capability as a tree in a @retains annotation.
575- // */
576- // object ReadOnlyCapabilityApply:
577- // def unapply(tree: Apply)(using Context): Option[Tree] = tree match
578- // case Apply(ro, arg :: Nil) if ro.symbol == defn.Caps_readOnlyCapability => Some(arg)
579- // case _ => None
580-
581572abstract class AnnotatedCapability (annotCls : Context ?=> ClassSymbol ):
582573 def apply (tp : Type )(using Context ): AnnotatedType =
583- assert(tp.isTrackableRef, i " not a trackable ref: $tp" )
584- tp match
585- case AnnotatedType (_, annot) =>
586- assert(! unwrappable.contains(annot.symbol), i " illegal combination of derived capabilities: $annotCls over ${annot.symbol}" )
587- case _ =>
588- tp match
589- case tp : Capability => tp.derivedRef(annotCls)
590- case _ => AnnotatedType (tp, Annotation (annotCls, util.Spans .NoSpan ))
574+ AnnotatedType (tp, Annotation (annotCls, util.Spans .NoSpan ))
591575
592- def unapply (tree : AnnotatedType )(using Context ): Option [Capability ] = tree match
593- case AnnotatedType (parent : Capability , ann) if ann.hasSymbol(annotCls) => Some (parent)
576+ def unapply (tree : AnnotatedType )(using Context ): Option [Type ] = tree match
577+ case AnnotatedType (parent : Type , ann) if ann.hasSymbol(annotCls) => Some (parent)
594578 case _ => None
595579
596- protected def unwrappable (using Context ): Set [Symbol ]
597580end AnnotatedCapability
598581
599- object QualifiedCapability :
600- def unapply (tree : AnnotatedType )(using Context ): Option [Capability ] = tree match
601- case AnnotatedType (parent : Capability , ann)
602- if defn.capabilityQualifierAnnots.contains(ann.symbol) => Some (parent)
603- case _ => None
604-
605582/** An extractor for `ref @readOnlyCapability`, which is used to express
606583 * the read-only capability `ref.rd` as a type.
607584 */
608- object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot ):
609- protected def unwrappable (using Context ) = Set ()
585+ object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot )
610586
611587/** An extractor for `ref @annotation.internal.reachCapability`, which is used to express
612588 * the reach capability `ref*` as a type.
613589 */
614- object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot ):
615- protected def unwrappable (using Context ) = Set (defn.ReadOnlyCapabilityAnnot )
590+ object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot )
616591
617592/** An extractor for all kinds of function types as well as method and poly types.
618593 * It includes aliases of function types such as `=>`. TODO: Can we do without?
0 commit comments