From f298f160e27800d6a23e0b3e1ad5876666ea4800 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:38:52 -0400 Subject: [PATCH 01/13] Too much certainty --- Guide.docc/CommonProblems.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 92206c9..26cfa15 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -1,6 +1,6 @@ # Common Compiler Errors -Identify, understand, and address common problems you'll encounter while +Identify, understand, and address common problems you can encounter while working with Swift concurrency. The data isolation guarantees made by the compiler affect all Swift code. From 1d5b5e50b0d9572ca252b4317dab126291bbc9aa Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:41:18 -0400 Subject: [PATCH 02/13] Awkard wording --- Guide.docc/CommonProblems.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 26cfa15..0312b4f 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -15,8 +15,8 @@ number of warnings and errors. _Don't_ get overwhelmed! Most of these can be tracked down to a much smaller set of root causes. And these causes, frequently, are a result of common patterns which aren't -just easy to fix, but can also very instructive in helping to understand -Swift's data isolation model. +just easy to fix, but can also be very instructive while learning about +Swift's concurrency system. ## Unsafe Global and Static Variables From db060df06a1b53446db0fa30efb759cbb94eec16 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:15:49 -0400 Subject: [PATCH 03/13] Missing word --- Guide.docc/CommonProblems.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 0312b4f..a85c572 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -72,7 +72,7 @@ func addNewStyle() { } ``` -One way to address the problem is by changing variable's isolation. +One way to address the problem is by changing the variable's isolation. ```swift @MainActor From d2a6dd8cef1d8197f53ff6a8986149e90046f8c1 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:26:30 -0400 Subject: [PATCH 04/13] remove keyword reference --- Guide.docc/CommonProblems.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index a85c572..94f827b 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -94,7 +94,7 @@ let supportedStyleCount = 42 If there is synchronization in place that protects this variable in a way that is invisible to the compiler, you can disable all isolation checking for -`supportedStyleCount` using the `nonisolated(unsafe)` keyword: +`supportedStyleCount` using `nonisolated(unsafe)`. ```swift /// This value is only ever accessed while holding `styleLock`. From 1fa153f3a24d41e1dd64b5b51fdc0d17790ebbd1 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:34:25 -0400 Subject: [PATCH 05/13] Simplify protocol static isolation --- Guide.docc/CommonProblems.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 94f827b..8e9695d 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -150,11 +150,8 @@ directly. ## Protocol Conformance Isolation Mismatch -A protocol defines requirements that a conforming type must satisfy. -Swift ensures that clients of a protocol can interact with its methods and -properties in a way that respects data isolation. -To do this, both the protocol itself and its requirements must specify -static isolation. +A protocol defines requirements that a conforming type must satisfy, +including static isolation. This can result in isolation mismatches between a protocol's declaration and conforming types. From dac3ac6d939ae10cea9c01222aa6ab86a7f628f4 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:53:14 -0400 Subject: [PATCH 06/13] Lots of clarification around adding isolation --- Guide.docc/CommonProblems.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 8e9695d..d66d08b 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -239,21 +239,26 @@ protocol Styler { } ``` -Marking a protocol with a global actor attribute implies global actor isolation -on all protocol requirements and extension methods. The global actor is also -inferred on conforming types when the conformance is not declared in an -extension. +Marking a protocol with a global actor attribute will infer isolation +for the entire scope of the conformance. +This can apply to a conforming type as a whole if the protocol conformance is +not declared in an extension. Per-requirement isolation has a narrower impact on actor isolation inference, -because inference only applies to the implementation of that requirement. It -does not impact the inferred isolation of protocol extensions or other methods -on the conforming type. This approach should be favored if it makes sense to -have conforming types that aren't necessarily also tied to the same global actor. +because it only applies to the implementation of that specific requirement. +It does not impact the inferred isolation of protocol extensions or other +methods on the conforming type. +This approach should be favored if it makes sense to have conforming types +that aren't necessarily also tied to the same global actor. Either way, changing the isolation of a protocol can affect the isolation of conforming types and it can impose restrictions on generic code using the -protocol in a generic requirement. You can stage in diagnostics caused by -adding global actor isolation on a protocol using `@preconcurrency`: +protocol. + +You can stage in diagnostics caused by adding global actor isolation on a +protocol using `@preconcurrency`. +This will preserve source compatibility with clients that have not yet +begun adopting concurrency. ```swift @preconcurrency @MainActor From 9d115dfe96a3598876f1faa3f2a427815ad8a453 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:56:23 -0400 Subject: [PATCH 07/13] Simplify how async requirements help --- Guide.docc/CommonProblems.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index d66d08b..a896c95 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -269,11 +269,9 @@ protocol Styler { #### Asynchronous Requirements -For methods that implement synchronous protocol requirements, either the -isolation of the method must match the isolation of the requirement exactly, -or the method must be `nonisolated`, meaning it can be called from -any isolation domain without risk of data races. Making a requirement -asynchronous offers a lot more flexibility over the isolation in +For methods that implement synchronous protocol requirements the isolation +of implementations must match exactly. +Making a requirement _asynchronous_ offers more flexibility for conforming types. ```swift From 986cc14e4d1099f320e2257d83e495cca226efcf Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:58:29 -0400 Subject: [PATCH 08/13] Remove redundant information --- Guide.docc/CommonProblems.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index a896c95..13c7ee0 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -280,9 +280,8 @@ protocol Styler { } ``` -Because `async` methods guarantee isolation by switching to the corresponding -actor in the implementation, it's possible to satisfy a non-isolated `async` -protocol requirement with an isolated method: +It's possible to satisfy a non-isolated `async` protocol requirement with +an isolated method. ```swift @MainActor From 2b9ce69d64d51aefea3b302bc0bd3ec3be2b3472 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:05:48 -0400 Subject: [PATCH 09/13] Simplify --- Guide.docc/CommonProblems.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 13c7ee0..f28a7e9 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -341,7 +341,7 @@ and the issue instead is only caused by the conforming type. #### Non-Isolated -Even a completely non-isolated function can still be useful. +Even a completely non-isolated function could still be useful. ```swift @MainActor @@ -353,11 +353,10 @@ class WindowStyler: Styler { } ``` -The downside to such an implementation is that isolated state and -functions become unavailable. -This is definitely a major constraint, but could still be -appropriate, especially if it is used exclusively as a source of -instance-independent configuration. +The constraint on this implementation is isolated state and functions +become unavailable. +This can still be an appropriate solution, especially if the function is used +as a source of instance-independent configuration. #### Conformance by Proxy From 1e7437e2611f496757b41419f3adc097062408f5 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:38:22 -0400 Subject: [PATCH 10/13] Remove redundant information --- Guide.docc/CommonProblems.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index f28a7e9..3aa9f65 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -462,9 +462,8 @@ public struct ColorComponents: Sendable { Even when trivial, adding `Sendable` conformance should always be done with care. -Remember that `Sendable` is a guarantee of thread-safety, and part of a -type's API contract. -Removing the conformance is an API-breaking change. +Remember that `Sendable` is a guarantee of thread-safety and +removing the conformance is an API-breaking change. ### Preconcurrency Import From 528c7fb96ebbb31db02a4d06be73ad8256612c94 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:43:04 -0400 Subject: [PATCH 11/13] Downgrade diagnostics --- Guide.docc/CommonProblems.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index 3aa9f65..b671497 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -469,8 +469,8 @@ removing the conformance is an API-breaking change. Even if the type in another module is actually `Sendable`, it is not always possible to modify its definition. -In this case, you can use a `@preconcurrency import` to suppress errors until -the library is updated. +In this case, you can use a `@preconcurrency import` to downgrade diagnostics +until the library is updated. ```swift // ColorComponents defined here @@ -485,8 +485,8 @@ func updateStyle(backgroundColor: ColorComponents) async { With the addition of this `@preconcurrency import`, `ColorComponents` remains non-`Sendable`. However, the compiler's behavior will be altered. -When using the Swift 6 language mode, the error produced here will be downgraded -to a warning. +When using the Swift 6 language mode, +the error produced here will be downgraded to a warning. The Swift 5 language mode will produce no diagnostics at all. ### Latent Isolation From 961baecd4ff56df4bda1512b613ae9d146a170d5 Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:03:52 -0400 Subject: [PATCH 12/13] reword --- Guide.docc/CommonProblems.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index b671497..b1edffb 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -681,7 +681,8 @@ see the associated [Swift evolution proposal][SE-0364]. #### Sendable Reference Types It is possible for reference types to be validated as `Sendable` without -the `unchecked` qualifier, but this is only done under very narrow circumstances. +the `unchecked` qualifier, +but this is only done under very specific circumstances. To allow a checked `Sendable` conformance, a class: From df9bca15fdd4bfe4842598e5fc86f339dcdfb86c Mon Sep 17 00:00:00 2001 From: Matt <85322+mattmassicotte@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:09:53 -0400 Subject: [PATCH 13/13] Value type, formatting --- Guide.docc/CommonProblems.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Guide.docc/CommonProblems.md b/Guide.docc/CommonProblems.md index b1edffb..6b3c281 100644 --- a/Guide.docc/CommonProblems.md +++ b/Guide.docc/CommonProblems.md @@ -700,10 +700,10 @@ final class Style: Sendable { } ``` -A reference type that conforms to `Sendable` is sometimes a sign that a struct -would be preferable, but there are circumstances where reference semantics need -to be preserved, or where compatibility with a mixed Swift/Objective-C code base -is required. +A reference type that conforms to `Sendable` is sometimes a sign that a value +type would be preferable. +But there are circumstances where reference semantics need to be preserved, +or where compatibility with a mixed Swift/Objective-C code base is required. #### Using Composition