From 60bb5cf448ac1e86b8aec5f28487fbb0817a1b2f Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Mon, 5 May 2025 17:56:09 -0700 Subject: [PATCH 1/9] Start outlining updates to 'nonisolated' --- TSPL.docc/ReferenceManual/Declarations.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index 46274f0fd..d3adfdbf7 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -2269,6 +2269,27 @@ A nonisolated member executes like code outside of the actor: It can't interact with any of the actor's isolated state, and callers don't mark it with `await` when using it. +XXX OUTLINE (additions for SE-0449): + +- Writing `nonisolated` on a type or protocol declaration + suppresses an implicit/inherited global actor isolation. + For example, given `@MainActor protocol P` + you can write `nonisolated protocol P2: P` and `nonisolated struct S: P` +- Writing `nonisolated` on an extension + applies to each declaration in the extension --- + the same as writing `@MainActor` on an extension, + but with the opposite effect. +- Writing `nonisolated` on a type declaration + doesn't apply to type declarations nested inside of it, + like how `@MainActor` doesn't. +- Writing `nonisolated` on a nonsendable stored property + lets you explicitly spell the implicit/default behavior. + +- ?? nonisolated inference from within the module + for mutable storage of sendable value types + ?? and annotating such storage with `nonisolated` + to allow synchronous access from outside the module + Members of an actor can be marked with the `@objc` attribute only if they are nonisolated or asynchronous. From 93a023d4ee83ad0afb8607f9467951fcb6273519 Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Wed, 7 May 2025 17:16:27 -0700 Subject: [PATCH 2/9] Finish outlining docs impact --- TSPL.docc/ReferenceManual/Declarations.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index d3adfdbf7..0e6014f5d 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -2284,11 +2284,9 @@ XXX OUTLINE (additions for SE-0449): like how `@MainActor` doesn't. - Writing `nonisolated` on a nonsendable stored property lets you explicitly spell the implicit/default behavior. - -- ?? nonisolated inference from within the module - for mutable storage of sendable value types - ?? and annotating such storage with `nonisolated` - to allow synchronous access from outside the module +- Writing `nonisolated` on (TR: stored?) sendable properties on sendable value types, + broadening the SE-0434 rule, + but only within the module. Members of an actor can be marked with the `@objc` attribute only if they are nonisolated or asynchronous. From 9a0ada6b332b6f9b9b6a06a374a24935bedf5bfc Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Thu, 8 May 2025 11:16:02 -0700 Subject: [PATCH 3/9] Rough in reference for nonisolated --- TSPL.docc/ReferenceManual/Declarations.md | 38 +++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index 0e6014f5d..f8beeb337 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -2268,25 +2268,37 @@ whose declarations are marked with the `nonisolated` keyword. A nonisolated member executes like code outside of the actor: It can't interact with any of the actor's isolated state, and callers don't mark it with `await` when using it. +You can write `nonisolated` in the following places: -XXX OUTLINE (additions for SE-0449): - -- Writing `nonisolated` on a type or protocol declaration - suppresses an implicit/inherited global actor isolation. - For example, given `@MainActor protocol P` - you can write `nonisolated protocol P2: P` and `nonisolated struct S: P` - Writing `nonisolated` on an extension - applies to each declaration in the extension --- - the same as writing `@MainActor` on an extension, - but with the opposite effect. + applies to each declaration in the extension. + - Writing `nonisolated` on a type declaration - doesn't apply to type declarations nested inside of it, - like how `@MainActor` doesn't. + applies to that type and its members, + but not to any nested type declarations. + +- Writing `nonisolated` on a type declaration or protocol declaration + suppresses an inherited global actor isolation. + For example, + if a protocol is declared as `@MainActor protocol SomeProtocol` + then types and protocols that conform to `SomeProtocol` + are also isolated to the main actor. + Writing `nonisolated protocol AnotherProtocol: SomeProtocol` + or `nonisolated struct SomeStroct: SomeProtocol` + suppresses that actor isolation. + - Writing `nonisolated` on a nonsendable stored property - lets you explicitly spell the implicit/default behavior. -- Writing `nonisolated` on (TR: stored?) sendable properties on sendable value types, + doesn't have any effect + because the property is already nonisolated by default. + However, you can write this to be explicit. + + + Members of an actor can be marked with the `@objc` attribute only if they are nonisolated or asynchronous. From edfdf7526ffd97474846109bd42fc8ff7706b99a Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Thu, 8 May 2025 13:06:36 -0700 Subject: [PATCH 4/9] Move 'nonisolated to declaration modifiers --- TSPL.docc/ReferenceManual/Declarations.md | 72 ++++++++++++----------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index f8beeb337..3b58223ef 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -2265,40 +2265,7 @@ but not to asynchronous functions. Actors can also have nonisolated members, whose declarations are marked with the `nonisolated` keyword. -A nonisolated member executes like code outside of the actor: -It can't interact with any of the actor's isolated state, -and callers don't mark it with `await` when using it. -You can write `nonisolated` in the following places: - -- Writing `nonisolated` on an extension - applies to each declaration in the extension. - -- Writing `nonisolated` on a type declaration - applies to that type and its members, - but not to any nested type declarations. - -- Writing `nonisolated` on a type declaration or protocol declaration - suppresses an inherited global actor isolation. - For example, - if a protocol is declared as `@MainActor protocol SomeProtocol` - then types and protocols that conform to `SomeProtocol` - are also isolated to the main actor. - Writing `nonisolated protocol AnotherProtocol: SomeProtocol` - or `nonisolated struct SomeStroct: SomeProtocol` - suppresses that actor isolation. - -- Writing `nonisolated` on a nonsendable stored property - doesn't have any effect - because the property is already nonisolated by default. - However, you can write this to be explicit. - - - +XXX delete the above or xref to new spot? Members of an actor can be marked with the `@objc` attribute only if they are nonisolated or asynchronous. @@ -3842,6 +3809,43 @@ that introduces the declaration. For an example of how to use the `lazy` modifier, see . +- term `nonisolated`: + + A nonisolated member executes like code outside of the actor: + It can't interact with any of the actor's isolated state, + and callers don't mark it with `await` when using it. + You can write `nonisolated` in the following places: + + - Writing `nonisolated` on an extension + applies to each declaration in the extension. + + - Writing `nonisolated` on a type declaration + applies to that type and its members, + but not to any nested type declarations. + + - Writing `nonisolated` on a type declaration or protocol declaration + suppresses an inherited global actor isolation. + For example, + if a protocol is declared as `@MainActor protocol SomeProtocol` + then types and protocols that conform to `SomeProtocol` + are also isolated to the main actor. + Writing `nonisolated protocol AnotherProtocol: SomeProtocol` + or `nonisolated struct SomeStroct: SomeProtocol` + suppresses that actor isolation. + + - Writing `nonisolated` on a nonsendable stored property + doesn't have any effect + because the property is already nonisolated by default. + However, you can write this to be explicit. + + + + - term `optional`: Apply this modifier to a protocol's property, method, or subscript members to indicate that a conforming type isn't required From 9793348edd336fe56e6d9a58fde84616fc4678f4 Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Thu, 8 May 2025 21:27:46 -0700 Subject: [PATCH 5/9] Reorganize and expand nonisolated reference --- TSPL.docc/ReferenceManual/Declarations.md | 81 +++++++++++++---------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index 3b58223ef..7b690281b 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -3810,41 +3810,54 @@ that introduces the declaration. see . - term `nonisolated`: + Apply this modifier to a declaration + to place it outside any actor's concurrency domain. + Nonisolated functions can run on any actor + and code running on any actor can access nonisolated values. + + + + When you mark an actor's method or property `nonisolated`, + callers don't mark it with `await` when calling or accessing it. + This can be a first step towards adopting concurrency, + by marking code that you want to move off of the main actor + and then using the compiler errors to guide refactoring. + + On a structure, class, enumeration, or protocol declaration, + `nonisolated` applies to that type and its members, + but not to any nested type declarations. + Writing `nonisolated` also suppresses any inferred global actor isolation. + + + ```swift + // Explicitly isolated to the main actor. + @MainActor protocol SomeProtocol + + // Implicitly isolated to the main actor. + protocol MyProtocol: SomeProtocol + struct MyStruct: SomeProtocol + + // Not isolated to the main actor. + nonisolated protocol AnotherProtocol: SomeProtocol + nonisolated struct AnotherStruct: SomeProtocol + ``` + + On an extension, + `nonisolated` applies to each declaration in the extension. + + On a nonsendable stored property, + `nonsendable` doesn't have any effect + because the property is already nonisolated by default. + However, you can write this to be explicit. + - A nonisolated member executes like code outside of the actor: - It can't interact with any of the actor's isolated state, - and callers don't mark it with `await` when using it. - You can write `nonisolated` in the following places: - - - Writing `nonisolated` on an extension - applies to each declaration in the extension. - - - Writing `nonisolated` on a type declaration - applies to that type and its members, - but not to any nested type declarations. - - - Writing `nonisolated` on a type declaration or protocol declaration - suppresses an inherited global actor isolation. - For example, - if a protocol is declared as `@MainActor protocol SomeProtocol` - then types and protocols that conform to `SomeProtocol` - are also isolated to the main actor. - Writing `nonisolated protocol AnotherProtocol: SomeProtocol` - or `nonisolated struct SomeStroct: SomeProtocol` - suppresses that actor isolation. - - - Writing `nonisolated` on a nonsendable stored property - doesn't have any effect - because the property is already nonisolated by default. - However, you can write this to be explicit. - - - + On sendable properties of a sendable value type, + but only within the module. + XXX broadening the SE-0434 rule, + - term `optional`: Apply this modifier to a protocol's property, method, From 15cbe9bac747b8355a563e584016fb6786592ad2 Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Fri, 16 May 2025 15:57:02 -0700 Subject: [PATCH 6/9] Link/redirect to the new 'nonisolated' docs --- TSPL.docc/ReferenceManual/Declarations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index 7b690281b..737339f06 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -2264,8 +2264,8 @@ to synchronous functions, but not to asynchronous functions. Actors can also have nonisolated members, -whose declarations are marked with the `nonisolated` keyword. -XXX delete the above or xref to new spot? +whose declarations are marked with the `nonisolated` keyword +as described in . Members of an actor can be marked with the `@objc` attribute only if they are nonisolated or asynchronous. From 38b4c8816a1ac0bb1af9033b74717bdc35d27a37 Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Thu, 22 May 2025 16:55:47 -0700 Subject: [PATCH 7/9] Fill in nonisolated reference --- TSPL.docc/ReferenceManual/Declarations.md | 64 ++++++++++++++++------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index 737339f06..abbdedbc8 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -3812,25 +3812,36 @@ that introduces the declaration. - term `nonisolated`: Apply this modifier to a declaration to place it outside any actor's concurrency domain. - Nonisolated functions can run on any actor - and code running on any actor can access nonisolated values. + This modifier suppresses any implicit isolation + to the main actor or another global actor. + Nonisolated functions can run on any actor, + and nonisolated variables and properties + are accessible from code running on any actor. + - When you mark an actor's method or property `nonisolated`, - callers don't mark it with `await` when calling or accessing it. + Nonisolated methods and nonisolated computed properties + can't directly access any actor-isolated state; + they use `await` like code outside the actor. + When you mark a method or property `nonisolated`, + code that calls or accesses it don't mark use `await`. This can be a first step towards adopting concurrency, by marking code that you want to move off of the main actor and then using the compiler errors to guide refactoring. - On a structure, class, enumeration, or protocol declaration, + On a structure, class, or enumeration declaration, `nonisolated` applies to that type and its members, but not to any nested type declarations. - Writing `nonisolated` also suppresses any inferred global actor isolation. - + + On a protocol declaration, + `nonisolated` suppresses any inferred global-actor isolation, + which allows conforming types to be either actor-isolated or nonisolated. ```swift // Explicitly isolated to the main actor. @@ -3848,16 +3859,33 @@ that introduces the declaration. On an extension, `nonisolated` applies to each declaration in the extension. - On a nonsendable stored property, - `nonsendable` doesn't have any effect - because the property is already nonisolated by default. - However, you can write this to be explicit. - + Nonsendable stored properties are nonisolated by default; + however, you can write this modifier to be explicit. + + + Sendable variables and properties are nonisolated by default, + when you access them within the same module. + + + - On sendable properties of a sendable value type, - but only within the module. - XXX broadening the SE-0434 rule, - + You can't write `nonisolated` on a declaration + that's also marked with `@MainActor` + or isolated to another global actor, + on a sendable type's property if that property's type isn't sendable, + or on a sendable class's stored property if that property is mutable. - term `optional`: Apply this modifier to a protocol's property, method, From a81dcbe4f2c36aa8bdbce80a2f0c9a9693573d6a Mon Sep 17 00:00:00 2001 From: Alex Martini Date: Wed, 28 May 2025 15:13:02 -0700 Subject: [PATCH 8/9] Clarify TR question --- TSPL.docc/ReferenceManual/Declarations.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/TSPL.docc/ReferenceManual/Declarations.md b/TSPL.docc/ReferenceManual/Declarations.md index abbdedbc8..b11417111 100644 --- a/TSPL.docc/ReferenceManual/Declarations.md +++ b/TSPL.docc/ReferenceManual/Declarations.md @@ -3817,7 +3817,12 @@ that introduces the declaration. Nonisolated functions can run on any actor, and nonisolated variables and properties are accessible from code running on any actor. - + +