-
Notifications
You must be signed in to change notification settings - Fork 103
Simplify the configuration option for synchronous test isolation. #747
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Simplify the configuration option for synchronous test isolation. #747
Conversation
This PR replaces `Configuration.isMainActorIsolationEnforced` with a new property `Configuration.defaultIsolationContext` which can be set to any actor, not just the main actor. This property is then used as the isolation context for synchronous test functions that are not otherwise actor-isolated. The typical use case for this property would be to set it to `MainActor.shared` so that synchronous test functions run on the main actor, but a testing tool might want to instead run them all on another actor or serial executor for performance (or other) reasons. This change isn't just speculative: it allows us to simplify the macro-generated thunk for synchronous test functions so that it does not need to emit the body of the thunk twice (once for the main actor, once for non-isolated.) This change wasn't possible before `#isolation` was introduced, but we'd already added `Configuration.isMainActorIsolationEnforced` when that happened so the timing didn't line up. By rewriting this part of the macro expansion, we're able to toss a bunch of support code that isn't needed anymore. Yay!
@swift-ci test |
I probably need to make the closure sendable. That sounds like a problem for Monday Jonathan. |
…tIsolationContext` property and use a local closure that the compiler can see is only called once, solving the consuming/borrowing problem.
Saturday Jonathan swooped in and rethinked/rethunked it. |
@swift-ci test |
…ip that bit back out
The line diff has shrunk, but mostly because I've added a bunch of comments trying to explain these shenanigans. |
@swift-ci test |
@swift-ci test |
…ed by @test (#759) Small cleanup from the changes in #747: Remove an unintentional parameter label which resulted in a parameter being named `isolated_` when it should be just `_`. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
@grynspan |
That property isn't something users of the testing library are intended to have access to control. What problem are you trying to solve? This conversation may be better in the Development > Swift Testing subcategory on the forums. |
…n code for synchronous test functions (#1067) This fixes a compilation error in code expanded from the `@Test` macro when it's attached to a synchronous (i.e. non-`async`) test function in a context where there is a concrete type named `Actor`. For example, the following code reproduces the error: ```swift // In MyApp public class Actor {} // In test code import Testing import MyApp // ❌ 'any' has no effect on concrete type 'Actor' // - 'isolated' parameter type 'Actor?' does not conform to 'Actor' or 'DistributedActor' @test func example() /* No 'async' */ {} ``` The macro code includes an unqualified reference to a type by that name, but it's intended to refer to the protocol in Swift's `_Concurrency` module. The fix is to ensure the macro's reference to this protocol is fully-qualified with a module name. This was first reported on the Swift Forums in https://forums.swift.org/t/error-isolated-parameter-type-actor-does-not-conform-to-actor-or-distributedactor/79190. This bug was introduced in #747, which first landed in Swift 6.1 and Xcode 16.3. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
…n code for synchronous test functions (swiftlang#1067) This fixes a compilation error in code expanded from the `@Test` macro when it's attached to a synchronous (i.e. non-`async`) test function in a context where there is a concrete type named `Actor`. For example, the following code reproduces the error: ```swift // In MyApp public class Actor {} // In test code import Testing import MyApp // ❌ 'any' has no effect on concrete type 'Actor' // - 'isolated' parameter type 'Actor?' does not conform to 'Actor' or 'DistributedActor' @test func example() /* No 'async' */ {} ``` The macro code includes an unqualified reference to a type by that name, but it's intended to refer to the protocol in Swift's `_Concurrency` module. The fix is to ensure the macro's reference to this protocol is fully-qualified with a module name. This was first reported on the Swift Forums in https://forums.swift.org/t/error-isolated-parameter-type-actor-does-not-conform-to-actor-or-distributedactor/79190. This bug was introduced in swiftlang#747, which first landed in Swift 6.1 and Xcode 16.3. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
…n code for synchronous test functions (swiftlang#1067) This fixes a compilation error in code expanded from the `@Test` macro when it's attached to a synchronous (i.e. non-`async`) test function in a context where there is a concrete type named `Actor`. For example, the following code reproduces the error: ```swift // In MyApp public class Actor {} // In test code import Testing import MyApp // ❌ 'any' has no effect on concrete type 'Actor' // - 'isolated' parameter type 'Actor?' does not conform to 'Actor' or 'DistributedActor' @test func example() /* No 'async' */ {} ``` The macro code includes an unqualified reference to a type by that name, but it's intended to refer to the protocol in Swift's `_Concurrency` module. The fix is to ensure the macro's reference to this protocol is fully-qualified with a module name. This was first reported on the Swift Forums in https://forums.swift.org/t/error-isolated-parameter-type-actor-does-not-conform-to-actor-or-distributedactor/79190. This bug was introduced in swiftlang#747, which first landed in Swift 6.1 and Xcode 16.3. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
This PR replaces
Configuration.isMainActorIsolationEnforced
with a new propertyConfiguration.defaultIsolationContext
which can be set to any actor, not just the main actor. This property is then used as the isolation context for synchronous test functions that are not otherwise actor-isolated.The typical use case for this property would be to set it to
MainActor.shared
so that synchronous test functions run on the main actor, but a testing tool might want to instead run them all on another actor or serial executor for performance (or other) reasons.This change isn't just speculative: it allows us to simplify the macro-generated thunk for synchronous test functions so that it does not need to emit the body of the thunk twice (once for the main actor, once for non-isolated.) This change wasn't possible before
#isolation
was introduced, but we'd already addedConfiguration.isMainActorIsolationEnforced
when that happened so the timing didn't line up.By rewriting this part of the macro expansion, we're able to toss a bunch of support code that isn't needed anymore. Yay!
Checklist: