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

**URL:** <https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060>\
**Category:** Announcements\
**Created:** [September 2, 2022, 3:39pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060 "2022-09-02T15:39:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [September 2, 2022, 3:39pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/1 "2022-09-02T15:39:55Z")

</div>

Hi all,

The [review](https://forums.swift.org/t/se-0371-isolated-synchronous-deinit/59754) for [SE-0371: "Isolated synchronous deinit"](https://github.com/apple/swift-evolution/blob/main/proposals/0371-isolated-synchronous-deinit.md) ran from August 18th to August 31st. The language workgroup has decided to return the proposal for revision.

Feedback was overall positive on solving the issue presented in the proposal, and there was no major disagreement around the semantics of the isolated `deinit`. However, there were some concerns around defaulting `deinit`s to being isolated and around the copying of task locals. Specifically, reviewers pointed out that defaulting `deinit` to isolated may introduce unnecessary hops (in addition to binary size and runtime costs), and that copying task locals was a potentially expensive operation that was not likely to be useful in practice. The workgroup did recognize, however, that there is value in having `deinit` receive a _consistent_ view of the task locals, rather than just receiving the task locals of whatever task happens to run the `deinit`.

There were also questions raised about how this feature might interact with a future, fully-fledged `deinit async` feature, and whether such a feature might subsume the need for special-case rules for isolated `deinit` by allowing us to align `init` and `deinit` isolation rules. The workgroup discussed these points but realizes that there is likely a lot of further design work that would go into the full `deinit async` feature, so it isn’t entirely clear whether or not it would be worth it to have a way to write an isolated `deinit` in the meantime.

For these reasons, the language workgroup has elected to request the following revisions:

- By default, `deinit` should behave the same as today, that is, it should be nonisolated and only able to access `Sendable` state. To achieve an isolated `deinit`, the user should have to opt-in explicitly. One syntax for this opt-in suggested in the review was `isolated deinit`.
- Task locals should not be copied for an isolated `deinit`. Instead, to ensure the `deinit` receives a consistent set of task locals, the task locals should be cleared before calling into the `deinit`.
- Inclusion of additional discussion around the future `deinit async` direction. The language workgroup is not certain whether it makes sense to delay the ability for `deinit` to access isolated state until the implementation of a significantly larger and more complex feature, but would still like to see a more thorough discussion of this future direction to help make the case that it is worth it to add isolated `deinit` _now_.

Once these revisions are made the language workgroup will run another review of the revised proposal.

Thank you for participating in Swift Evolution.

---

<div class="post-metadata">

**Author:** ![Stan\_Smida](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stan_smida/32/10999_2.png) [@Stan\_Smida](https://forums.swift.org/u/Stan_Smida)\
**Post date:** [March 31, 2023, 1:50pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/2 "2023-03-31T13:50:09Z")

</div>

May I ask if there is any progress / priority / estimation around this?

If I understand it correctly, there is currently no way how to gracefully shutdown pending items isolated to the actor in `deinit`?

These may by pending URL tasks, opened file handlers, locks, closures that require to call a completion, expensive executions, files to be deleted, memory to be freed, potentially notifications / eventns to be fired or even observers and schedulers to be cancelled (unowned, indirect). Lots of stuff... Is there a workaround to this or why aren't people concerned about it?

---

<div class="post-metadata">

**Author:** ![bobspryn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bobspryn/32/22465_2.png) [@bobspryn](https://forums.swift.org/u/bobspryn)\
**Post date:** [September 27, 2023, 9:30pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/3 "2023-09-27T21:30:27Z")

</div>

Also curious about this. I sometimes have long-running Tasks in my actor that I'd like to shutdown without resorting to a manual `shutdown` method of some sort.

---

<div class="post-metadata">

**Author:** ![BrentM](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/brentm/32/15134_2.png) [@BrentM](https://forums.swift.org/u/BrentM)\
**Post date:** [October 14, 2023, 2:22am UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/4 "2023-10-14T02:22:00Z")

</div>

> [@Stan\_Smida](#):
>
> May I ask if there is any progress / priority / estimation around this?
> 
> If I understand it correctly, there is currently no way how to gracefully shutdown pending items isolated to the actor in `deinit`?
> 
> These may by pending URL tasks, opened file handlers, locks, closures that require to call a completion, expensive executions, files to be deleted, memory to be freed, potentially notifications / eventns to be fired or even observers and schedulers to be cancelled (unowned, indirect). Lots of stuff... Is there a workaround to this or why aren't people concerned about it?

I am concerned about it. The inability to cancel some long running/infinite tasks has already caused a few problems for me today. I hope this feature comes soon.

---

<div class="post-metadata">

**Author:** ![jasonbobier](https://avatars.discourse-cdn.com/v4/letter/j/85e7bf/32.png) [@jasonbobier](https://forums.swift.org/u/jasonbobier)\
**Post date:** [October 28, 2023, 1:06pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/5 "2023-10-28T13:06:11Z")

</div>

I just ran into this too and would love this to be completed.

---

<div class="post-metadata">

**Author:** ![tcldr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tcldr/32/24405_2.png) [@tcldr](https://forums.swift.org/u/tcldr)\
**Post date:** [November 3, 2023, 1:43pm UTC](https://forums.swift.org/t/returned-for-revision-se-0371-isolated-synchronous-deinit/60060/6 "2023-11-03T13:43:12Z")

</div>

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.

> [@Jumhyn](#):
>
> However, there were some concerns around defaulting `deinit`s to being isolated

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`.

> [@SE-0371: Isolated synchronous deinit](https://forums.swift.org/t/se-0371-isolated-synchronous-deinit/59754/3):
>
> We should not align `deinit` with methods, but with `init`, specifically:
> 
> ```swift
> actor A { 
> let x: Int
> 
> init() {
> self.x = 12
> // NO HOP, because not-`async` (!)
> // can't touch isolated properties; body is effectively nonisolated here
> }
> 
> init() async {
> self.x = 12
> // HOP, because `async` (!)
> doThings()
> }
> }
> 
> ```

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

```swift

@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 `deinit`s.

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`/`deinit`s 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.
