I'm learning about @MainActor using a command-line app. This code gives me an error:
@MainActor
func show(photo: String) {
// Display photo on the UI
print("Displaying \(photo)")
}
show(photo: "cat")
Error: Call to main actor-isolated global function 'show(photo:)' in a synchronous nonisolated context
My project is old, but running the same code in a new command-line app gives the same error. I thought that all code in a command-line app ran in the main actor, so I expected the call to the function to work. Putting the call inside a Task and adding await makes the error go away but I want to know why it is there in the first place. Is there a better way to experiment with @MainActor in main.swift?
Xcode 26.6, Strict Concurrency Checking: Minimal, Default Actor Isolation: nonisolated, Approachable Concurrency: No, Lanugage Version: Swift 5
By having concurrency checking set to minimal and using the Swift 5 mode, you've essentially turned off the compiler's ability and willingness to reason about concurrency. I suggest you switch to Swift 6 mode, as that will turn on most of the compiler's brains, and will better prepare you for real usage.
Thanks for your answer. I'm using a project that I created a couple of years ago for testing all code and I've only just discovered that these concurrency settings exist at all. For consistency I keep all project settings the same, so I can learn from my own mistakes. After more digging it turns out that the error is probably a bug.
After more digging I found a bug report from 2024 with this behaviour.
Top-level code is implicitly MainActor isolated so calling a @MainActor isolated function should not require a suspension point and Swift correctly warns about a redundant await.
However, when the very first (awaitable) call is to a @MainActor isolated function, Swift outputs an error when not using await.
Adding an await to the first function call in my code, and then repeating the same function call with no await gives no error:
@MainActor
func show(photo: String) {
// Display photo on the UI
print("Displaying \(photo)")
}
// Warning: No 'async' operations occur within 'await' expression
await show(photo: "cat")
show(photo: "cat")
// Displaying cat
// Displaying cat