Karl
(👑🦆)
May 10, 2024, 10:47am
3
This was discussed in the proposal review.
There was concern that the restriction is too soft and too advisory, since it is not transitively enforced. Async functions can freely call unannotated non-async functions, which in turn can freely call nonasync functions on behalf of the async caller. Despite not being a bulletproof transitive property, the Core Team still believes that the guidance provided by non-transitive enforcement is valuable. Unannotated non-async wrappers can help shape the usage of the unavailable-from-async raw APIs in ways that make them safer to use from async contexts; for instance, if a lock/unlock API is made unavailable from async, because it is generally not a good idea to take a lock in a task when the unlock may happen while the task is running on a different thread, then the library can provide a scoped withLock
API that isn't made unavailable from async. Although the wrapper is calling functions that were individually considered unsafe to use from async, since the wrapper would itself be non-async, it avoids the problem of potentially switching threads mid-execution, thereby making the entire operation safer to use from async contexts. Even if it isn't a strict, transitive prohibition on accessing certain operations from async contexts, this proposal provides a tool for guiding users toward the correct code patterns to use instead.
I even tried (unsuccessfully) to advocate for a model where noasync
would be transitive up to an explicit marker when you said it was async-safe again, to address the case of async-unsafe functions composing to something that is safe.
A transitive restriction would definitely be more powerful for asserting correctness, but would also be much more disruptive to the existing ecosystem, and in our judgment, the Core Team didn't think the cost/benefit tradeoff of a transitive restriction made sense for this functionality, especially when there is already a large transition underway for Sendable
restrictions coming in Swift 6.
3 Likes