Isaaс Weisberg
Isaaс Weisberg

Reputation: 2814

Async call to a func defined in extension from an isolated function in an actor preserves the isolation?

I have this setup:

protocol Foo {
    func foo() async
}

extension Foo {
    func foo() async {
        print("default implementation")
    }
}

final actor Bar: Foo {
    func run() async {
         print("this function is isolated on actor Bar")
         await self.foo()
    }

}

Question: will the foo be run on the actor Bar? Or the actor will be released because it's an async call outside the scope of actor?

Upvotes: 1

Views: 83

Answers (1)

Rob Napier
Rob Napier

Reputation: 299265

No.

If foo() were really in the same isolation context, then it should be able to access synchronous function without awaiting. And I could define that:

protocol Foo {
    func foo() async
    func sync()  // Adding a new synchronous requirement
}

extension Foo {
    func foo() async {
        print("default implementation")
        sync() // And this should be fine
    }
}

But it is not possible to implement this with an actor within its isolation:

final actor Bar: Foo {
    func run() async { ... }

    func sync() {}
    // -> Actor-isolated instance method 'sync()' cannot be used to satisfy nonisolated protocol requirement
}

In order for Bar to implement Foo, sync() must be nonisolated:

// This is fine
final actor Bar: Foo {
    func run() async { ... }

    nonisolated func sync() {}
}

So the default implementation of foo() cannot synchronously access isolated parts of Bar.

Upvotes: 1

Related Questions