Synchronous getter vs. @MainActor property — why is this allowed?

How is it possible that I can conform to a protocol requiring a synchronous getter and also mark the concrete property as @MainActor at the same time?

protocol MyProtocol {
    var syncStuff: String { get }
}


class MyClass: MyProtocol {
    var x = "sdfgsdfgd"

    @MainActor
    var syncStuff: String {
        return x
    }
}


Task.detached {
    let instance: MyProtocol = MyClass()
    let x = instance.syncStuff
    print(x)

    let instance2 = MyClass()
    let y = await instance2.syncStuff
    print(y)
}

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

In Swift 6 mode, functions with this kind of mismatch (sync requirement vs. @MainActor implementation) are flagged as errors. But for property getters, this compiles and runs without error.

1 Like

In 6.2, if I compile this with -swift-version 6, I get an error about MyClass not implementing MyProtocol correctly:

error: conformance of 'MyClass' to protocol 'MyProtocol' crosses into main actor-isolated code and can cause data races [#ConformanceIsolation]

If I use -swift-version 5 then the code compiles as you said.