mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
It's ok to drop the global-actor qualifier `@G` from a function's type if:
- the cast is happening in a context isolated to global-actor `G`
- the function value will not be `@Sendable`
- the function value is not `async`
It's primarily safe to drop the attribute because we're already in the
same isolation domain. So it's OK to simply drop the global-actor
if we prevent the value from later leaving that isolation domain.
This means we no longer need to warn about code like this:
```
@MainActor func doIt(_ x: [Int], _ f: @MainActor (Int) -> ()) {
x.forEach(f)
// warning: converting function value of type '@MainActor (Int) -> ()' to '(Int) throws -> Void' loses global actor 'MainActor'
}
```
NOTE: this implementation is a bit gross in that the constraint solver
might emit false warnings about casts it introduced that are actually
safe. This is mainly because closure isolation is only fully determined
after constraint solving. See the FIXME's for more details.
resolves rdar://94462333
31 lines
845 B
Swift
31 lines
845 B
Swift
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
|
|
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: OS=macosx
|
|
|
|
import SwiftUI
|
|
|
|
@MainActor func someMainActorFn() {}
|
|
|
|
struct ContentView: View {
|
|
var body: some View {
|
|
VStack {
|
|
// In the future this warning should go away too, but it remains since the isolation of the closure
|
|
// passed to the VStack is not inferred yet during constraint solving.
|
|
// expected-warning@+1 {{converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'}}
|
|
Button(action: someMainActorFn) {
|
|
Text("Sign In")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ContentViewExplicitAnnotation: View {
|
|
var body: some View {
|
|
VStack { @MainActor in
|
|
Button(action: someMainActorFn) {
|
|
Text("Sign In")
|
|
}
|
|
}
|
|
}
|
|
} |