There isn't a difference between async actor methods and normal async methods. Both can have inout
parameters. The restrictions we need are on which arguments you can provide, to ensure that you have exclusive access to the argument to the inout
even across a suspension. The actor proposal states the restriction for actor-isolated instance members:
Actor-isolated stored properties can be passed into synchronous functions via inout parameters, but it is ill-formed to pass them to asynchronous functions via inout parameters. For example:
func modifiesSynchronously(_: inout Double) { }
func modifiesAsynchronously(_: inout Double) async { }
extension BankAccount {
func wildcardBalance() async {
modifiesSynchronously(&balance) // okay
await modifiesAsynchronously(&balance) // error: actor-isolated property 'balance' cannot be passed 'inout' to an asynchronous function
}
}
This restriction prevents exclusivity violations where the modification of the actor-isolated balance is initiated by passing it as inout to a call that is then suspended, and another task executed on the same actor then fails with an exclusivity violation in trying to access balance itself.
It doesn't matter whether modifiesAsynchronously
is on an actor or not; you still can't pass &self.balance
to it.
However, it would be fine to pass &myLocalVariable
to it so long as we've already ensured that myLocalVariable
doesn't have captures that can run concurrently. That's partially implemented as a warning in the experimental concurrency mode, and I promised (somewhere these threads) to bring that into one of the proposals... but haven't done so yet.
Doug