I wonder if controlling this with a command line flag/build setting is hiding important information too much. Different build systems will have to devise different ways to express this (or just let the user pass raw compiler flags), but those can often become distant from the code itself, making it hard for the user to track down why certain behavior is happening the way that it is.
Similarly, I'm not sure this alternative/possible future direction could work:
extension SwiftSetting {
@available(_PackageDescription, introduced: 6.2)
public static func defaultIsolation(
_ globalActor: (any GlobalActor.Type)?,
_ condition: BuildSettingCondition? = nil
) -> SwiftSetting
}
SwiftSetting.defaultIsolation(MyGlobalActor.self)
...because the package manifest would have to depend on the client code that defines the global actor type. MainActor.Type
works here serendipitously because it's in the standard library.
You mention as another future direction a way to specify arbitrary compiler settings in a source file, but what if we could avoid that for this feature by baking it into existing language semantics? Similar to how you can overwrite defaults like IntegerLiteralType
in a file, we could give the user the option of defining something in their module:
typealias DefaultActorIsolation = MainActor
And the compiler could attempt to resolve that within the module being compiled when deciding which isolation to use. If the typealias is undefined, it would default to nonisolated
behavior. And if we wanted to support arbitrary actors in the future, that becomes straightforward.
(We could even draw a distinction between a fileprivate
alias and an internal
alias if we wanted to support per-file vs. per-module isolation, but I'm also not sure if that's desirable.)
Would that be a feasible approach? I think it would also be helpful from a tooling perspective to be able to see the default isolation directly expressed in the source file, instead of only being accessible through compilation command lines.