@autoclosure @escaping

hello I'm studying swift from the manual The Swift Programming Language: Redirect
line 4 generates this error
"Main actor-isolated var 'customerProviders' can not be mutated from a nonisolated context"

I double-checked that I had written everything correctly but I can't understand why it generates an error

1 var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
2 var customerProviders: [() -> String] = []

3 func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
4    customerProviders.append(customerProvider)
5 }

Hi, this is due to the so-called “Strict concurrency checking“, introduced in Swift 6, the newest language version. It tries to prevent data-races by ensuring a variable can only get accessed by one thread at a time.

In your case it‘s an unwanted side effect, there are currently plans to prevent this.

Without going into to much detail, customerProviders, as a global variable, is implicitly isolated to the “Main Actor“, so it can only be mutated from functions also isolated to that actor. This makes sure, that only one mutation can happen at the same time.

To fix your issue, you have to add an annotation to your function:

 var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
 var customerProviders: [() -> String] = []

@MainActor func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
    customerProviders.append(customerProvider)
 }

I don‘t know how far you are in the book, but at some point this will make sense to you, for now, you just have to live with it. That being said, 1. this has to be fixed in the book, and 2. it‘s a prime example on why [Prospective Vision] Improving the approachability of data-race safety needs to be realized.

2 Likes

perfect, thank you