@@ -90,33 +90,33 @@ object Capabilities:
9090 */
9191 case class Maybe (underlying : Capability ) extends DerivedCapability
9292
93- /** The readonly capability `x.rd`. We have {x.rd} <: {x}.
94- *
95- * Read-only capabilities cannot wrap maybe capabilities
96- * but they can wrap reach capabilities. We have
97- * (x?).readOnly = (x.rd)?
98- */
99- case class ReadOnly (underlying : ObjectCapability | RootCapability | Reach | Restricted )
100- extends DerivedCapability
101-
10293 /** The restricted capability `x.only[C]`. We have {x.only[C]} <: {x}.
10394 *
104- * Restricted capabilities cannot wrap maybe capabilities or read-only capabilities
95+ * Restricted capabilities cannot wrap maybe capabilities
10596 * but they can wrap reach capabilities. We have
10697 * (x?).restrict[T] = (x.restrict[T])?
10798 * (x.rd).restrict[T] = (x.restrict[T]).rd
10899 */
109- case class Restricted (underlying : ObjectCapability | RootCapability | Reach , cls : ClassSymbol )
100+ case class Restricted (underlying : CoreCapability | RootCapability | Reach , cls : ClassSymbol )
110101 extends DerivedCapability
111102
103+ /** An extractor for the read-only capability `x.rd`. `x.rd` is represented as
104+ * `c.only[caps.Read]`.
105+ */
106+ object ReadOnly :
107+ def apply (underlying : CoreCapability | RootCapability | Reach | Restricted )(using Context ): Restricted =
108+ Restricted (underlying.stripRestricted.asInstanceOf , defn.Caps_Read )
109+ def unapply (ref : Restricted )(using Context ): Option [CoreCapability | RootCapability | Reach ] =
110+ if ref.cls == defn.Caps_Read then Some (ref.underlying) else None
111+
112112 /** If `x` is a capability, its reach capability `x*`. `x*` stands for all
113113 * capabilities reachable through `x`.
114114 * We have `{x} <: {x*} <: dcs(x)}` where the deep capture set `dcs(x)` of `x`
115115 * is the union of all capture sets that appear in covariant position in the
116116 * type of `x`. If `x` and `y` are different variables then `{x*}` and `{y*}`
117117 * are unrelated.
118118 *
119- * Reach capabilities cannot wrap read-only capabilities or maybe capabilities.
119+ * Reach capabilities cannot wrap restricted capabilities or maybe capabilities.
120120 * We have
121121 * (x?).reach = (x.reach)?
122122 * (x.rd).reach = (x.reach).rd
@@ -132,7 +132,7 @@ object Capabilities:
132132 object GlobalCap extends RootCapability :
133133 def descr (using Context ) = " the universal root capability"
134134 override val maybe = Maybe (this )
135- override val readOnly = ReadOnly (this )
135+ override def readOnly ( using Context ) = ReadOnly (this )
136136 override def restrict (cls : ClassSymbol )(using Context ) = Restricted (this , cls)
137137 override def reach = unsupported(" cap.reach" )
138138 override def singletonCaptureSet (using Context ) = CaptureSet .universal
@@ -346,23 +346,21 @@ object Capabilities:
346346 case self : Maybe => self
347347 case _ => cached(Maybe (this ))
348348
349- def readOnly : ReadOnly | Maybe = this match
349+ def readOnly ( using Context ) : Restricted | Maybe = this match
350350 case Maybe (ref1) => Maybe (ref1.readOnly)
351- case self : ReadOnly => self
352- case self : (ObjectCapability | RootCapability | Reach | Restricted ) => cached(ReadOnly (self))
351+ case self @ ReadOnly (_) => self
352+ case self : (CoreCapability | RootCapability | Reach | Restricted ) => cached(ReadOnly (self))
353353
354- def restrict (cls : ClassSymbol )(using Context ): Restricted | ReadOnly | Maybe = this match
354+ def restrict (cls : ClassSymbol )(using Context ): Restricted | Maybe = this match
355355 case Maybe (ref1) => Maybe (ref1.restrict(cls))
356- case ReadOnly (ref1) => ReadOnly (ref1.restrict(cls).asInstanceOf [Restricted ])
357356 case self @ Restricted (ref1, prevCls) =>
358357 val combinedCls = leastClassifier(prevCls, cls)
359358 if combinedCls == prevCls then self
360359 else cached(Restricted (ref1, combinedCls))
361- case self : (ObjectCapability | RootCapability | Reach ) => cached(Restricted (self, cls))
360+ case self : (CoreCapability | RootCapability | Reach ) => cached(Restricted (self, cls))
362361
363- def reach : Reach | Restricted | ReadOnly | Maybe = this match
362+ def reach : Reach | Restricted | Maybe = this match
364363 case Maybe (ref1) => Maybe (ref1.reach)
365- case ReadOnly (ref1) => ReadOnly (ref1.reach.asInstanceOf [Reach | Restricted ])
366364 case Restricted (ref1, cls) => Restricted (ref1.reach.asInstanceOf [Reach ], cls)
367365 case self : Reach => self
368366 case self : ObjectCapability => cached(Reach (self))
@@ -377,9 +375,9 @@ object Capabilities:
377375 case tp : SetCapability => tp.captureSetOfInfo.isReadOnly
378376 case _ => this ne stripReadOnly
379377
378+ /** The restriction of this capability or NoSymbol if there is none */
380379 final def restriction (using Context ): Symbol = this match
381380 case Restricted (_, cls) => cls
382- case ReadOnly (ref1) => ref1.restriction
383381 case Maybe (ref1) => ref1.restriction
384382 case _ => NoSymbol
385383
@@ -397,10 +395,9 @@ object Capabilities:
397395 case Maybe (ref1) => ref1.stripReadOnly.maybe
398396 case _ => this
399397
400- /** Drop restrictions with clss `cls` or a superclass of `cls` */
398+ /** Drop restrictions with class `cls` or a superclass of `cls` */
401399 final def stripRestricted (cls : ClassSymbol )(using Context ): Capability = this match
402400 case Restricted (ref1, cls1) if cls.isSubClass(cls1) => ref1
403- case ReadOnly (ref1) => ref1.stripRestricted(cls).readOnly
404401 case Maybe (ref1) => ref1.stripRestricted(cls).maybe
405402 case _ => this
406403
@@ -409,7 +406,6 @@ object Capabilities:
409406
410407 final def stripReach (using Context ): Capability = this match
411408 case Reach (ref1) => ref1
412- case ReadOnly (ref1) => ref1.stripReach.readOnly
413409 case Restricted (ref1, cls) => ref1.stripReach.restrict(cls)
414410 case Maybe (ref1) => ref1.stripReach.maybe
415411 case _ => this
@@ -591,7 +587,6 @@ object Capabilities:
591587 def computeHiddenSet (f : Refs => Refs )(using Context ): Refs = this match
592588 case self : FreshCap => f(self.hiddenSet.elems)
593589 case Restricted (elem1, cls) => elem1.computeHiddenSet(f).map(_.restrict(cls))
594- case ReadOnly (elem1) => elem1.computeHiddenSet(f).map(_.readOnly)
595590 case _ => emptyRefs
596591
597592 /** The transitive classifiers of this capability. */
@@ -609,8 +604,6 @@ object Capabilities:
609604 assert(cls != defn.AnyClass )
610605 if cls == defn.NothingClass then ClassifiedAs (Nil )
611606 else ClassifiedAs (cls :: Nil )
612- case ReadOnly (ref1) =>
613- ref1.transClassifiers
614607 case Maybe (ref1) =>
615608 ref1.transClassifiers
616609 case Reach (_) =>
@@ -634,8 +627,6 @@ object Capabilities:
634627 case Restricted (_, cls1) =>
635628 assert(cls != defn.AnyClass )
636629 cls1.isSubClass(cls)
637- case ReadOnly (ref1) =>
638- ref1.tryClassifyAs(cls)
639630 case Maybe (ref1) =>
640631 ref1.tryClassifyAs(cls)
641632 case Reach (_) =>
@@ -656,7 +647,6 @@ object Capabilities:
656647 cs.forall(c => leastClassifier(c, cls) == defn.NothingClass )
657648 case _ => false
658649 isEmpty || ref1.isKnownEmpty
659- case ReadOnly (ref1) => ref1.isKnownEmpty
660650 case Maybe (ref1) => ref1.isKnownEmpty
661651 case _ => false
662652
@@ -717,7 +707,6 @@ object Capabilities:
717707 case _ => false
718708 || viaInfo(y.info)(subsumingRefs(this , _))
719709 case Maybe (y1) => this .stripMaybe.subsumes(y1)
720- case ReadOnly (y1) => this .stripReadOnly.subsumes(y1)
721710 case Restricted (y1, cls) => this .stripRestricted(cls).subsumes(y1)
722711 case y : TypeRef if y.derivesFrom(defn.Caps_CapSet ) =>
723712 // The upper and lower bounds don't have to be in the form of `CapSet^{...}`.
@@ -801,7 +790,6 @@ object Capabilities:
801790 y.isKnownClassifiedAs(cls) && x1.maxSubsumes(y, canAddHidden)
802791 case _ =>
803792 y match
804- case ReadOnly (y1) => this .stripReadOnly.maxSubsumes(y1, canAddHidden)
805793 case Restricted (y1, cls) => this .stripRestricted(cls).maxSubsumes(y1, canAddHidden)
806794 case _ => false
807795
@@ -889,7 +877,6 @@ object Capabilities:
889877 case c : DerivedCapability =>
890878 val c1 = c.underlying.toType
891879 c match
892- case _ : ReadOnly => ReadOnlyCapability (c1)
893880 case Restricted (_, cls) => OnlyCapability (c1, cls)
894881 case _ : Reach => ReachCapability (c1)
895882 case _ : Maybe => MaybeCapability (c1)
0 commit comments