While capturing self
in the unstructured task is a soundness problem. Spawning any unstructured work in deinits can open up remote denial of service attacks in applications.
During the second review of SE-0371: Isolated synchronous deinit @johannesweiss and I brought up our concerns with how implicit spawning of such unstructured work in deinits is dangerous. The same arguments apply for explicit spawning.
In general, I would love to see us explore ~SyncConsumable
as a language feature. ~Copyable
already brings us pretty close except that we cannot model asynchronous clean up. Types such as file descriptors, sockets or other resources that need async cleanup need to resort to using with-style
methods instead.
One area to explore more is if a hypothetical deinit() async
should really be implicitly awaited or if they need to be explicitly awaited. In similar veins, what about throwing deinits? My experience is that most async
methods also want to become throws
at some point.
The Rust project has an async drop initiative where they went through a similar exploration.