@@ -218,14 +218,18 @@ Some conclusions:
218
218
219
219
* Any kind of observable side-effects are not allowed, like ` print ` , file IO, etc.
220
220
221
+ The ` readnone ` attribute cannot be used on functions that take
222
+ nontrivial owned arguments for the reasons explained in the next
223
+ section on ` @_effects(readonly) ` .
224
+
221
225
### ` @_effects(readonly) `
222
226
223
227
Defines that the function does not have any observable memory writes or any
224
228
other observable side effects, beside reading of memory.
225
229
226
230
Similar to ` readnone ` , a ` readonly ` function is allowed to write to local objects.
227
231
228
- A function can be marked as ` readonly ` if it’s save to eliminate a call to such
232
+ A function can be marked as ` readonly ` if it’s safe to eliminate a call to such
229
233
a function in case its return value is not used.
230
234
Example:
231
235
@@ -254,6 +258,44 @@ between those calls the member `i` of the class instance could be modified:
254
258
255
259
The same conclusions as for ` readnone ` also apply to ` readonly ` .
256
260
261
+ The ` readonly ` and ` readnone ` effects are sensitive to the ARC calling
262
+ convention, which normally has no effect on language semantics. These
263
+ effects attributes can only be used correctly by knowing whether the
264
+ compiler will pass any nontrivial arguments as guaranteed or owned. If
265
+ the function takes an owned argument, as is the case for initializers
266
+ and setters, then ` readonly ` is likely invalid because removing the call
267
+ would fail to release the argument. Additionally, the release itself
268
+ may run a tree of deinitializers with potentially arbitrary side
269
+ effects.
270
+
271
+ In special situations, the library author may still want to use
272
+ ` readonly ` for functions with owned arguments. They must be able to
273
+ guarantee that the owned arguments are not effectively released from
274
+ the caller's perspective. This could be because all paths through the
275
+ function have an equivalent retain, or they may know that the argument
276
+ is a tagged object for which a release has no effect. To make sure
277
+ this is intentional, the library author must also explicitly specify
278
+ ` _effects(releasenone) ` even though that is normally already implied
279
+ by ` readonly ` .
280
+
281
+ For example, it is valid to give the following trivial initializer
282
+ ` readonly ` and ` releasenone ` attributes:
283
+
284
+ @_effects(readonly) @_effects(releasenone)
285
+ init(_ c: C) { self.c = c }
286
+
287
+ If ` C ` is a class, then the value returned by the initializer must
288
+ have at least one use in the form of a release. The optimizer,
289
+ therefore, may not remove the call to the initializer without
290
+ deliberately compensating for ownership.
291
+
292
+ For the same reason that developers must take care regarding argument
293
+ ownership, the compiler must always check for ` readonly ` and
294
+ ` readnone ` effects attributes before transforming a function
295
+ signature. Normally, this optimization can be done independent of
296
+ language semantics, but such optimizations should be avoided for
297
+ functions with these effects attributes.
298
+
257
299
### ` @_effects(releasenone) `
258
300
259
301
Defines that the function does not release any class instance.
0 commit comments