Reconsider inference of global actor based on property wrappers

I just encountered this and find it very unexpected, and its currently presenting a pretty big hurdle in adopting async/await.

i have some existing propertyWrappers that ensure that i am calling them on the main-thread.

simplified version here

struct OnMainThread<Value> {
    var _wrapped: Value
  
    public var wrappedValue: Value {
        set {
            dispatchPrecondition(condition: .onQueue(.main))
            _wrapped = newValue
        }
        get {
            dispatchPrecondition(condition: .onQueue(.main))
            _wrapped
        }
    }
}

and im often using initializers with default-expressions

class MyContainer {
     let contained = Contained() // error: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context
}

class Contained {
    @OnMainThread var int = 1
}

this pattern is quite common in our codebase

i now wanted to introduce the @MainActor on my propertyWrapper and it breaks in a LOT of places.

I find the behaviour very unintuitive, since i have not annotated the Contained class itself with @MainActor

Is there room to reconsider this?

1 Like