Warning in nonisolated init setting constants


After updating to Xcode 15.3, I get the warning:

:warning: Main actor-isolated property 'foo' can not be mutated from a non-isolated context; this is an error in Swift 6

in code constructs like this:

final class SomeViewModel: ObservableObject {
  @Published private(set) var state = ...
  private let foo: String
  private let bar: (String) -> Void

  nonisolated init(
    foo: String,
    bar: @escaping (String) -> Void
  ) {
    self.foo = foo // <-- No warning here
    self.bar = bar // <-- Warning here



  1. Why shouldn't I be able to set private constants in the initialiser of a class like this from a non-isolated context? (The instance is not created, so how can it be "mutating" the private let property?

  2. Why do I only get the warning for bar and not also for foo?

  3. Is adding nonisolated to the private let property with the warning an acceptable fix for this?

1 Like

String conforms to Sendable, so it is safe for foo to cross isolation boundary. Closure you pass to init is not. Adding @Sendable attribute will fix the warning.

Because bar property by not being sendable cannot safely cross isolation boundary (from main-actor isolation to nonisolated context) at the time of assign. Probably, compiler message here not that descriptive; the case not in "mutability", but non-Sendable closure is crossing isolation boundary.

  1. Is adding nonisolated to the private let property with the warning an acceptable fix for this?

Hmm, the warning is still there after adding nonisolated like this:

  nonisolated private let bar: (String) -> Void

Depends on use case, e.g. you would need to access this nonisolated property from nonisolated context. Making it @Sendable will make it usable within the class easily, and probably this is better strategy to resolve the warning.

1 Like

There's an explanation for why this happens at Assigning to a `let` instance variable in nonisolated init - #4 by hborla

tldr; the compiler should not let you write nonisolated on stored properties of Sendable/actor-isolated types when the stored property type is not Sendable. This is fixed in the Swift 6 language mode.