Hello, this is a question regarding the interaction of MainActor-by-default, isolated conformances, and libraries. In Swift 6.2.
I maintain a library that defines a protocol, let's call it LibProtocol
.
This protocol is intended to be used across multiple isolation domains, even though it does not require Sendable
. To be precise:
- (REQ1) The protocol comes with static functions and properties that are invoked from various isolation domains.
- (REQ2) Instances, even if not Sendable, are supposed to be sent across isolation domains. That's what the lib does (you can think downloading structs from internet, decoded in a background thread until they are given to the app on the main actor, or loading stuff from a database, etc.). The user may only use instances on the main actor, but the library has instances cross isolation domains. That's its very job.
In an app that uses MainActor by default (as the new default Xcode 26 template does), a user type that conforms to LibProtocol
is MainActor-isolated, and its conformance is MainActor-isolated as well:
import Lib
// MainActor-isolated type
// MainActor-isolated conformance to LibProtocol
struct UserType: LibProtocol { }
This conflicts with how the protocol is intended to be used.
If the library declares LibProtocol
as a sub-protocol of SendableMetaType
, this solves REQ1 described above. But not REQ2:
The user type is still MainActor-isolated. I see plenty of other compiler errors regarding "Circular reference", "Conformance of 'UserType' to protocol 'Encodable' crosses into main actor-isolated code and can cause data races", "Conformance of 'UserType' to protocol 'LibProtocol' crosses into main actor-isolated code and can cause data races". Not a welcoming experience at all
One way to solve those errors is for the user to specify that the type is nonisolated
:
import Lib
nonisolated struct UserType: LibProtocol { }
I wish end users would not have to write this explicit nonisolated
. Assuming my understanding is not too wrong, can the library declare that LibProtocol
implies nonisolated? i.e. can the lib force an app to give up the default MainActor-isolation for types that conform to LibProtocol
?