@@ -83,24 +83,32 @@ object Mutability:
8383 if mbr.symbol.is(Method ) then mbr.symbol.isUpdateMethod
8484 else ! mbr.symbol.hasAnnotation(defn.UntrackedCapturesAnnot )
8585
86- /** OK, except if `tp` extends `Stateful` but `tp`'s capture set is non-exclusive */
87- private def exclusivity (using Context ): Exclusivity =
86+ /** OK, except if `tp` extends `Stateful` but `tp`'s capture set is non-exclusive
87+ * @param required if true, exclusivity can be obtained by setting the mutability
88+ * status of some capture set variable from Ignored to Writer.
89+ */
90+ private def exclusivity (required : Boolean )(using Context ): Exclusivity =
8891 if tp.derivesFrom(defn.Caps_Stateful ) then
8992 tp match
90- case tp : Capability if tp.isExclusive => Exclusivity .OK
91- case _ => tp.captureSet.exclusivity(tp)
93+ case tp : Capability if tp.isExclusive(required) => Exclusivity .OK
94+ case _ =>
95+ if tp.captureSet.isExclusive(required) then Exclusivity .OK
96+ else Exclusivity .ReadOnly (tp)
9297 else Exclusivity .OK
9398
94- /** Test conditions (1) and (2) listed in `adaptReadOnly` below */
95- private def exclusivityInContext (using Context ): Exclusivity = tp match
99+ /** Test conditions (1) and (2) listed in `adaptReadOnly` below
100+ * @param required if true, exclusivity can be obtained by setting the mutability
101+ * status of some capture set variable from Ignored to Writer.
102+ */
103+ private def exclusivityInContext (required : Boolean = false )(using Context ): Exclusivity = tp match
96104 case tp : ThisType =>
97105 if tp.derivesFrom(defn.Caps_Stateful )
98106 then ctx.owner.inExclusivePartOf(tp.cls)
99107 else Exclusivity .OK
100108 case tp @ TermRef (prefix : Capability , _) =>
101- prefix.exclusivityInContext.andAlso(tp.exclusivity)
109+ prefix.exclusivityInContext(required) .andAlso(tp.exclusivity(required) )
102110 case _ =>
103- tp.exclusivity
111+ tp.exclusivity(required)
104112
105113 def expectsReadOnly (using Context ): Boolean = tp match
106114 case tp : PathSelectionProto =>
@@ -109,10 +117,6 @@ object Mutability:
109117 tp.isValueType
110118 && (! tp.isStatefulType || tp.captureSet.mutability == CaptureSet .Mutability .Reader )
111119
112- extension (cs : CaptureSet )
113- private def exclusivity (tp : Type )(using Context ): Exclusivity =
114- if cs.isExclusive then Exclusivity .OK else Exclusivity .ReadOnly (tp)
115-
116120 extension (ref : TermRef | ThisType )
117121 /** Map `ref` to `ref.readOnly` if its type extends Mutble, and one of the
118122 * following is true:
@@ -122,7 +126,7 @@ object Mutability:
122126 */
123127 def adjustReadOnly (pt : Type )(using Context ): Capability = {
124128 if ref.derivesFromStateful
125- && (pt.expectsReadOnly || ref.exclusivityInContext != Exclusivity .OK )
129+ && (pt.expectsReadOnly || ref.exclusivityInContext() != Exclusivity .OK )
126130 then ref.readOnly
127131 else ref
128132 }.showing(i " Adjust RO $ref vs $pt = $result" , capt)
@@ -131,7 +135,7 @@ object Mutability:
131135 * of a field of `qualType`.
132136 */
133137 def checkUpdate (qualType : Type , pos : SrcPos )(msg : => String )(using Context ): Unit =
134- qualType.exclusivityInContext match
138+ qualType.exclusivityInContext(required = true ) match
135139 case Exclusivity .OK =>
136140 case err =>
137141 report.error(em " $msg\n since ${err.description(qualType)}. " , pos)
@@ -238,8 +242,8 @@ object Mutability:
238242 case improved @ CapturingType (parent, refs)
239243 if parent.derivesFrom(defn.Caps_Stateful )
240244 && expected.isValueType
241- && refs.isExclusive
242- && ! original.exclusivityInContext.isOK =>
245+ && refs.isExclusive()
246+ && ! original.exclusivityInContext() .isOK =>
243247 improved.derivedCapturingType(parent, refs.readOnly)
244248 .showing(i " Adapted readonly $improved for $tree with original = $original in ${ctx.owner} --> $result" , capt)
245249 case improved =>
0 commit comments