public static var whenDifferent: ShouldEmitValue<StateType> { .when(!=) }
causes
Converting non-sendable function value to '@Sendable (StateType, StateType) -> Bool' may introduce data races
same for ==
works fine with
public static var whenDifferent: ShouldEmitValue<StateType> { .when{ $0 != $1 } }
Swift concurrency really drives me crazy
public enum ShouldEmitValue<StateType>: Sendable {
// private let evaluate: (StateType, StateType) -> Bool
/// It will always emit changes, regardless of previous and new state
case always
/// It will never emit changes, regardless of previous and new state
case never
/// It's a custom-defined predicate, you'll be given old and new state, and must return a Bool indicating what you've decided from that change,
/// being `true` when you want this change to be notified, or `false` when you want it to be ignored.
case when(@Sendable (StateType, StateType) -> Bool)
}
extension ShouldEmitValue where StateType: Equatable {
// Converting non-sendable function value to '@Sendable (StateType, StateType) -> Bool' may introduce data races
public static var whenDifferent: ShouldEmitValue<StateType> { .when(!=) }
}
Var 'globalCounter' is not concurrency-safe because it is nonisolated global shared mutable state
Swift 6 does not allow you to do such stuff.
You can do something like
class NonSendableClass {
var value: Int = 0
}
struct Foo: Equatable {
let i: Int
let nonSendable = NonSendableClass()
@Sendable
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.nonSendable.value += 1 // Data race!
return lhs.i == rhs.i
}
}
let equal: @Sendable (Foo, Foo) -> Bool = { $0 == $1 }
and it works. How can equal
to be @Sendable?
It does not make sense at all.
I am trying to switch to Swift 6.
Swift 5 is fine, it just shows a lot of warnings.
I think it's just an inference limitation.
When the compiler cannot infer a sendable closure, or when it cannot upgrade a free-form function to a sendable closure, there's no downside to explicit mark it. Just as you did in .when{ $0 != $1 }
.
Though, I do think it's a good question to ask: whether we can treat any global functions to be automatically Sendable
.
When SE-0302 came out, there wasn't much discussions about global variables, so it was pretty possible for global functions to capture unsafe global state. Now, we have SE-0412 fixing many holes, I believe it is legit to review the question again.
Trying for a while, I cannot come up with any counter-examples, maybe the experts in this area can share some thoughts? @hborla
1 Like