@MainActor class ViewModel: ObservableObject {} @propertyWrapper struct Wrapper { var wrappedValue: T } @propertyWrapper struct MainWrapper { @MainActor var wrappedValue: T } //---------------------------------------- struct Foo1 { var viewModel: ViewModel = ViewModel() // ERROR: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context } struct Foo2 { @StateObject var viewModel: ViewModel = ViewModel() // Compile OK } struct Foo3 { @Wrapper var viewModel: ViewModel = ViewModel() // ERROR: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context } struct Foo4 { @MainWrapper var viewModel: ViewModel = ViewModel() // Compile OK } struct Foo5 { @MainWrapper var viewModel: ViewModel = ViewModel() // Compile OK // Compile OK, even though it looks same as Foo1, // because `Foo5.init` will automatically gain `@MainActor` by `@MainWrapper`, // and `MainWrapper.init` will automatically gain `@MainActor` by `@MainActor var wrappedValue`. var viewModel2: ViewModel = ViewModel() } // NOTE: Requires `@MainActor`, although there is no `@MainActor Foo5` or `@MainActor init`. func testFoo5() { _ = Foo5() // ERROR: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context }