@@ -91,33 +91,33 @@ object Capabilities:
9191 */
9292 case class Maybe (underlying : Capability ) extends DerivedCapability
9393
94- /** The readonly capability `x.rd`. We have {x.rd} <: {x}.
95- *
96- * Read-only capabilities cannot wrap maybe capabilities
97- * but they can wrap reach capabilities. We have
98- * (x?).readOnly = (x.rd)?
99- */
100- case class ReadOnly (underlying : ObjectCapability | RootCapability | Reach | Restricted )
101- extends DerivedCapability
102-
10394 /** The restricted capability `x.only[C]`. We have {x.only[C]} <: {x}.
10495 *
105- * Restricted capabilities cannot wrap maybe capabilities or read-only capabilities
96+ * Restricted capabilities cannot wrap maybe capabilities
10697 * but they can wrap reach capabilities. We have
10798 * (x?).restrict[T] = (x.restrict[T])?
10899 * (x.rd).restrict[T] = (x.restrict[T]).rd
109100 */
110- case class Restricted (underlying : ObjectCapability | RootCapability | Reach , cls : ClassSymbol )
101+ case class Restricted (underlying : CoreCapability | RootCapability | Reach , cls : ClassSymbol )
111102 extends DerivedCapability
112103
104+ /** An extractor for the read-only capability `x.rd`. `x.rd` is represented as
105+ * `c.only[caps.Read]`.
106+ */
107+ object ReadOnly :
108+ def apply (underlying : CoreCapability | RootCapability | Reach | Restricted )(using Context ): Restricted =
109+ Restricted (underlying.stripRestricted.asInstanceOf , defn.Caps_Read )
110+ def unapply (ref : Restricted )(using Context ): Option [CoreCapability | RootCapability | Reach ] =
111+ if ref.cls == defn.Caps_Read then Some (ref.underlying) else None
112+
113113 /** If `x` is a capability, its reach capability `x*`. `x*` stands for all
114114 * capabilities reachable through `x`.
115115 * We have `{x} <: {x*} <: dcs(x)}` where the deep capture set `dcs(x)` of `x`
116116 * is the union of all capture sets that appear in covariant position in the
117117 * type of `x`. If `x` and `y` are different variables then `{x*}` and `{y*}`
118118 * are unrelated.
119119 *
120- * Reach capabilities cannot wrap read-only capabilities or maybe capabilities.
120+ * Reach capabilities cannot wrap restricted capabilities or maybe capabilities.
121121 * We have
122122 * (x?).reach = (x.reach)?
123123 * (x.rd).reach = (x.reach).rd
@@ -133,7 +133,7 @@ object Capabilities:
133133 object GlobalCap extends RootCapability :
134134 def descr (using Context ) = " the universal root capability"
135135 override val maybe = Maybe (this )
136- override val readOnly = ReadOnly (this )
136+ override def readOnly ( using Context ) = ReadOnly (this )
137137 override def restrict (cls : ClassSymbol )(using Context ) = Restricted (this , cls)
138138 override def reach = unsupported(" cap.reach" )
139139 override def singletonCaptureSet (using Context ) = CaptureSet .universal
@@ -347,23 +347,21 @@ object Capabilities:
347347 case self : Maybe => self
348348 case _ => cached(Maybe (this ))
349349
350- def readOnly : ReadOnly | Maybe = this match
350+ def readOnly ( using Context ) : Restricted | Maybe = this match
351351 case Maybe (ref1) => Maybe (ref1.readOnly)
352- case self : ReadOnly => self
353- case self : (ObjectCapability | RootCapability | Reach | Restricted ) => cached(ReadOnly (self))
352+ case self @ ReadOnly (_) => self
353+ case self : (CoreCapability | RootCapability | Reach | Restricted ) => cached(ReadOnly (self))
354354
355- def restrict (cls : ClassSymbol )(using Context ): Restricted | ReadOnly | Maybe = this match
355+ def restrict (cls : ClassSymbol )(using Context ): Restricted | Maybe = this match
356356 case Maybe (ref1) => Maybe (ref1.restrict(cls))
357- case ReadOnly (ref1) => ReadOnly (ref1.restrict(cls).asInstanceOf [Restricted ])
358357 case self @ Restricted (ref1, prevCls) =>
359358 val combinedCls = leastClassifier(prevCls, cls)
360359 if combinedCls == prevCls then self
361360 else cached(Restricted (ref1, combinedCls))
362- case self : (ObjectCapability | RootCapability | Reach ) => cached(Restricted (self, cls))
361+ case self : (CoreCapability | RootCapability | Reach ) => cached(Restricted (self, cls))
363362
364- def reach : Reach | Restricted | ReadOnly | Maybe = this match
363+ def reach : Reach | Restricted | Maybe = this match
365364 case Maybe (ref1) => Maybe (ref1.reach)
366- case ReadOnly (ref1) => ReadOnly (ref1.reach.asInstanceOf [Reach | Restricted ])
367365 case Restricted (ref1, cls) => Restricted (ref1.reach.asInstanceOf [Reach ], cls)
368366 case self : Reach => self
369367 case self : ObjectCapability => cached(Reach (self))
@@ -893,7 +891,7 @@ object Capabilities:
893891 case c : DerivedCapability =>
894892 val c1 = c.underlying.toType
895893 c match
896- case _ : ReadOnly => ReadOnlyCapability (c1)
894+ case ReadOnly (_) => ReadOnlyCapability (c1)
897895 case Restricted (_, cls) => OnlyCapability (c1, cls)
898896 case _ : Reach => ReachCapability (c1)
899897 case _ : Maybe => MaybeCapability (c1)
0 commit comments