Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'

Note:
This is not a SwiftUI question, I was more concerned about the error thrown.

Overview:

  • I am encountering the error Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'

Questions:

  1. Is this a bug in the SwiftUI API not accepting main actor closure or am I missing something?
  2. Is there a way to resolve the issue without having to place the contents of buttonAction inside the action closure (as shown in the second button)?

Environment

  • Build Setting: Strict Concurrency Checking > Complete
  • Xcode: Version 14.0 beta 3 (14A5270f)
  • macOS: 13.0 Beta (22A5295i)

Code:

@MainActor
class Model: ObservableObject {
    func f1() {}
}

struct ContentView: View {
    
    @StateObject private var model = Model()
    
    var body: some View {
        VStack {
            //Error: Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'
            Button(action: buttonAction) {
                Text("Tap me")
            }

            //Compiles fine
            Button {
                buttonAction()
            } label: {
                Text("Tap me")
            }
        }
    }
    
    func buttonAction() {
        model.f1()
    }
}
1 Like

Submitted feedback FB10859400

What happens for this version?

Button(action: model.f1) {
	Text("Tap me")
}

Thanks @tera, the same error is thrown even for your code as well.

This happens only when the build setting Strict Concurrency Checking is set as Complete.

Based on Eliminate data races using Swift Concurrency - WWDC22 - Videos - Apple Developer (24:41 min) the build setting is mentioned.