[Returned for revision] SE-0371: Isolated synchronous deinit

Very pleased to see there's a potential solution to resolve this.

With Actors promoted as a way to 'protect shared mutable state', in practice that often means a wrapper for a bunch of non-Sendable conforming types. So, the requirement that members of an actor must also be Sendable to be accessible in the deinit is rather non-intuitive.

I think this is fair enough, but I have to say the asymmetry around isolation between a types init/deinit and its members is pretty confusing and seems inconsistent. The example given for actor initializers in the review shows that actor initializers are, by default, non-isolated, and therefore we should follow the same example for deinit.

And yet, for GAITs, it seems we are isolated:


@MainActor class GAIT {
  
  let x: Int
  
  init(x: Int) {
    self.x = x
    doStuff() // No sweat.
  }
  
  func doStuff() {
    print("x: \(x)")
  }
}

So it seems by the logic of the review, we should at least default GAITs to have isolated deinits.

More broadly though, I wish there was someway of getting consistency across these various types. It seems that the most intuitive solution would have been to require actors and GAITs to mark their init/deinits with nonisolated if that was indeed the context they'd be called in – leaving the defaults to be isolated (or not available) – but perhaps that ship has now sailed.

2 Likes