Add a chapter to the Language Reference for data-race safety.#372
Add a chapter to the Language Reference for data-race safety.#372hborla wants to merge 1 commit into
Conversation
| concurrent executor. | ||
|
|
||
| A non-isolated asynchronous function that runs on the caller's actor is | ||
| deonated with the `nonisolated(nonsending)` keyword: |
There was a problem hiding this comment.
Hah, yes, thank you. I should use a spell checker :)
heckj
left a comment
There was a problem hiding this comment.
spell check updates - no wording changes.
| Eliminate data races at compile time. | ||
|
|
||
| The Swift 6 language mode eliminates data races at compile time by | ||
| identifying and diagnosing risk of concurrent access to shared state. |
There was a problem hiding this comment.
| identifying and diagnosing risk of concurrent access to shared state. | |
| identifying and diagnosing the risk of concurrent access to shared state. |
| 3. The variable is a property of a struct and the type of the property | ||
| conforms to `Sendable`. | ||
|
|
||
| Extensions be marked with `nonisolated`, which promptes Swift to infer |
There was a problem hiding this comment.
| Extensions be marked with `nonisolated`, which promptes Swift to infer | |
| Extensions can be marked with `nonisolated`, which promptes Swift to infer |
| concurrent executor. | ||
|
|
||
| A non-isolated asynchronous function that runs on the caller's actor is | ||
| deonated with the `nonisolated(nonsending)` keyword: |
There was a problem hiding this comment.
| deonated with the `nonisolated(nonsending)` keyword: | |
| denoted with the `nonisolated(nonsending)` keyword: |
| to an actor to a different actor or a concurrent task. Swift ensures | ||
| that access to actor-isolated state only happens within the actor. You | ||
| can access `nonisolated` properties and methods from outside the actor, | ||
| but access to isolated properties and methods must be done asynchornously. |
There was a problem hiding this comment.
| but access to isolated properties and methods must be done asynchornously. | |
| but access to isolated properties and methods must be done asynchronously. |
| are either: | ||
|
|
||
| 1. Non-isolated and have `Sendable` type, or | ||
| 2. Isolated to a global actor |
There was a problem hiding this comment.
| 2. Isolated to a global actor | |
| 2. Isolated to a global actor. |
| A global variable is safe from data races if one of the following | ||
| conditions applies: | ||
|
|
||
| 1. It is a `let`-constant and the type conforms to `Sendable` |
There was a problem hiding this comment.
| 1. It is a `let`-constant and the type conforms to `Sendable` | |
| 1. It is a `let`-constant and the type conforms to `Sendable`. |
| conditions applies: | ||
|
|
||
| 1. It is a `let`-constant and the type conforms to `Sendable` | ||
| 2. It is isolated to a global actor |
There was a problem hiding this comment.
| 2. It is isolated to a global actor | |
| 2. It is isolated to a global actor. |
| } | ||
| ``` | ||
|
|
||
| The implementation of an `@concurrent` function will always switch off |
There was a problem hiding this comment.
An @Concurrent? Or do we say the "at"?
|
|
||
| * If `r` is synchronous, then `r'` is safe from data races if one of the | ||
| following conditions applies: | ||
| * The isolation of `r'` matches the isolation of `r'` |
There was a problem hiding this comment.
| * The isolation of `r'` matches the isolation of `r'` | |
| * The isolation of `r'` matches the isolation of `r` |
| * `r'` is `nonisolated` | ||
| * If `r` is asynchronous, then the implementation `r'` is safe from data | ||
| races if one of the following conditions applies: | ||
| * The isolation of `r'` matches the isolation of `r'` |
There was a problem hiding this comment.
| * The isolation of `r'` matches the isolation of `r'` | |
| * The isolation of `r'` matches the isolation of `r` |
| mutating func toggle() | ||
| } | ||
|
|
||
| struct Switch: Togglable { |
There was a problem hiding this comment.
| struct Switch: Togglable { | |
| struct Switch { |
| You specify that a declaration is non-isolated with the `nonisolated` | ||
| keyword. Swift guarantees that non-isolated declarations are safe | ||
| to call from anywhere by ensuring that they do not access actor-isolated | ||
| state in their implementation. Non-isolated functions safely call other |
There was a problem hiding this comment.
It's also OK for non-isolated function to access actor properties which are let-constants and of Sendable types. I think it might be worth adding this information, because it's common when conforming an actor to protocols.
This change adds a chapter to the TSPL Language Reference on data-race safety. This is meant to be an exhaustive list of semantic rules that define away low-level data races in Swift code. This is not meant to be an introduction to concurrency -- that's the job of the Concurrency chapter of the Language Guide -- and it's not meant to contain all semantic rules about the concurrency model (such as when async functions are guaranteed to not suspend dynamically, etc). This reference will subsume the data-race safety reference in the Swift migration guide, and is largely inspired by the content there, originally written by @mattmassicotte (thank you!)
I think this documentation is appropriate for the TSPL Language Reference based on the statement in the style guide on the purpose of the reference:
This data-race safety reference is currently not comprehensive, hence the draft state of this PR, and there are a number of missing concepts off the top of my head, including:
sendingparametersasync letI also have not done a sweep over all concurrency-related proposals to make sure their data race safety rules are covered by this reference.