Skip to content

[Concurrency] Diagnose captures of self in a task created in deinit. #75224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 13, 2024

Conversation

hborla
Copy link
Member

@hborla hborla commented Jul 13, 2024

This is done by diagnosing captures of self in escaping sending or @Sendable closures inside a deinit, which almost certainly means self will outlive deinit at runtime, which is a fatal error. This is a common mistake to make when creating isolated tasks inside nonisolated deinits to workaround the lack of synchronous isolated deinits in Swift 6.

Resolves: #72893

Note that this PR contains the commits from #75135. Only the last commit of this PR is relevant.

hborla added 5 commits July 10, 2024 11:58
…mances

in favor of explicit available ones.

The type checker does not support the notion of multiple protocol
conformances; there can only be one conformance, and if that conformance
is unavailable, you cannot specify your own available conformance. This
is important for Sendable checking; if a framework specifies that a type
is explicitly not Sendable with an unavailable Sendable conformance,
clients cannot ignore Sendable violations involving that type. If a
superclass wants to allow subclasses to add a Sendable conformance, it
should not declare an unavailable Sendable conformance.
…rom the

defining module, and diagnose redundant Sendable conformances.

We still allow re-stating inherited unchecked Sendable conformances in
subclasses because inherited Sendable conformances are surprising when
they opt out of static checking. Otherwise, warning on redundant Sendable
conformances nudges programmers toward cleaning up unnecessary retroactive
Sendable conformances over time as libraries incrementally add the
conformances directly.
Sendable conformances for source compatibility.

If conformance lookup always prefers the conformance from the defining module,
libraries introducing unavailable Sendable conformances can break source in
clients that declare retroactive Sendable conformances. Instead, still prefer
the available conformance, and always diagnose the client conformance as
redundant (as a warning). Then, when the retroactive conformance is removed,
the errors will surface, so the programmer has to take explicit action to
experience the source break.
This is done by diagnosing captures of `self` in escaping `sending` or
`@Sendable` closures inside a deinit, which almost certainly means `self`
will outlive deinit at runtime, which is a fatal error. This is a common
mistake to make when creating isolated tasks inside nonisolated deinits
to workaround the lack of synchrnous isolated deinits in Swift 6.
@hborla
Copy link
Member Author

hborla commented Jul 13, 2024

@swift-ci please smoke test

Copy link
Contributor

@ktoso ktoso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the last commit here specifically, looks good :) I thought we already diagnosed this huh, so great catch!

@hborla
Copy link
Member Author

hborla commented Jul 13, 2024

@swift-ci please smoke test macOS

@hborla hborla merged commit 73ba98c into swiftlang:main Jul 13, 2024
3 checks passed
@hborla hborla deleted the self-capture-deinit-task branch July 13, 2024 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing diagnostic when capturing self in deinit Task
2 participants