Hello,
Is it a breaking change to add Sendable
requirements to public apis? By "breaking change" I mean that userland code would stop compiling with an error in any of the concurrency checking modes (minimal, targeted, complete). Warnings are not a breaking change.
I'm thinking about this kind of changes:
// Library interface
-public protocol MyProtocol { ... }
+public protocol MyProtocol: Sendable { ... }
-public func f(_ closure: @escaping () -> Void) { ... }
+public func f(_ closure: @escaping @Sendable () -> Void) { ... }
-public func g<T>(_ closure: @escaping () -> T) { ... }
+public func g<T: Sendable>(_ closure: @escaping () -> T) { ... }
A little bit of context may clarify my question.
I maintain the library GRDB which currently requires Swift 5.7+ / Xcode 14+. It ships with some asynchronous functions, but has not been fully revised for sendability. Many apis that should eventually require Sendable input still allow non sendable values and closures. To be clear, I have audited the code and know what it would take, but I didn't make the changes because I was not sure they would be 100% backward compatible.
As time passes, more and more concurrency-related features ship in the compiler, and more and more users are compiling their apps with strict concurrency checkings. This is good. Recently, SE-0412 has just changed the landscape. GRDB is now a library that introduces warnings in user applications (warnings that the user can not fix in a satisfying way):
extension Author {
// Warning: Static property 'books' is not concurrency-safe
// because it is not either conforming to 'Sendable' or
// isolated to a global actor; this is an error in Swift 6.
static let books = hasMany(Book.self)
}
I want to preserve the excellent reputation of the library, so I am eager to remove those warnings. This means adding Sendable
to a bunch of public protocols and closures.
So far, I could see that those changes introduce new warnings in userland code, such as the ones below:
- non-final class 'UserClass' cannot conform to 'Sendable'; use '@unchecked Sendable'
- Capture of 'value' with non-sendable type 'UserClass' in a
@Sendable
closure - Converting non-sendable function value to '@Sendable () -> Void' may introduce data races
I could not come up with userland code that would stop compiling with a hard compiler error. But I'm not 100% sure that no user application will stop compiling. I don't know if adding sendability annotations are a breaking change or not. I don't know if fixing GRDB warnings will force me to bump the major version, or not.
Can anyone help answering this question? Thanks in advance.