@@ -86,15 +86,24 @@ extension (tree: Tree)
86
86
case Apply (TypeApply (_, refs :: Nil ), _) => refs.tpe
87
87
case _ =>
88
88
if tree.symbol.maybeOwner == defn.RetainsCapAnnot
89
- then ref( defn.captureRoot) else NoType
89
+ then defn.captureRoot.termRef else NoType
90
90
91
91
extension (tp : Type )
92
92
93
- def retainedElementsRaw (using Context ): List [Type ] = tp match
93
+ def toCapabilities (using Context ): List [Capability ] = tp match
94
94
case ReachCapability (tp1) =>
95
- tp1.reach :: Nil
95
+ tp1.toCapabilities.map(_. reach)
96
96
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
98
107
case OrType (tp1, tp2) =>
99
108
tp1.retainedElementsRaw ++ tp2.retainedElementsRaw
100
109
case tp =>
@@ -103,9 +112,7 @@ extension (tp: Type)
103
112
else tp :: Nil // should be checked by wellformedness
104
113
105
114
def retainedElements (using Context ): List [Capability ] =
106
- retainedElementsRaw.map:
107
- case tp : CaptureRef => tp
108
- case tp => throw IllegalCaptureRef (tp)
115
+ retainedElementsRaw.flatMap(_.toCapabilities)
109
116
110
117
/** Is this type a Capability that can be tracked?
111
118
* This is true for
@@ -539,57 +546,25 @@ class CleanupRetains(using Context) extends TypeMap:
539
546
RetainingType (tp, defn.NothingType , byName = annot.symbol == defn.RetainsByNameAnnot )
540
547
case _ => mapOver(tp)
541
548
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
-
558
549
abstract class AnnotatedCapability (annotCls : Context ?=> ClassSymbol ):
559
550
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 ))
568
552
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)
571
555
case _ => None
572
556
573
- protected def unwrappable (using Context ): Set [Symbol ]
574
557
end AnnotatedCapability
575
558
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
-
582
559
/** An extractor for `ref @readOnlyCapability`, which is used to express
583
560
* the read-only capability `ref.rd` as a type.
584
561
*/
585
- object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot ):
586
- protected def unwrappable (using Context ) = Set ()
562
+ object ReadOnlyCapability extends AnnotatedCapability (defn.ReadOnlyCapabilityAnnot )
587
563
588
564
/** An extractor for `ref @annotation.internal.reachCapability`, which is used to express
589
565
* the reach capability `ref*` as a type.
590
566
*/
591
- object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot ):
592
- protected def unwrappable (using Context ) = Set (defn.ReadOnlyCapabilityAnnot )
567
+ object ReachCapability extends AnnotatedCapability (defn.ReachCapabilityAnnot )
593
568
594
569
/** An extractor for all kinds of function types as well as method and poly types.
595
570
* It includes aliases of function types such as `=>`. TODO: Can we do without?
0 commit comments