Add defer_before_unstructured_task rule - #6857
Open
alisher-zinullayev wants to merge 1 commit into
Open
Conversation
Flags a `defer` block that assigns to shared state right before a sibling unstructured `Task` (or `Task.detached`) reads that same state. The deferred assignment runs the instant the enclosing synchronous scope returns, before the Task's body has a chance to run, inverting the intended order — most commonly seen as a loading flag being reset before the async work it guards has actually finished. Closes realm#6619
alisher-zinullayev
force-pushed
the
defer-before-unstructured-task
branch
from
August 6, 2026 11:32
95c2e97 to
8b1ecf7
Compare
Generated by 🚫 Danger |
Author
|
@SimplyDanny Would you mind taking a look when you have a chance? This implements the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the rule proposed in #6619: flags a
deferblock that assigns toshared state right before a sibling unstructured
Task(orTask.detached)reads that same state.
The
deferred assignment runs the instant the enclosing synchronous scopereturns, before the
Task's body has a chance to run — inverting theintended order. The canonical example is a loading flag being reset before
the async work it's guarding has actually finished:
Heuristic (opt-in, narrow, false-negative-friendly)
Triggers when all of the following hold, per the shape proposed in the issue:
defersits in a synchronous function/closure (notasync).x = ...orself.x = ...), which filters out logging-only defers and lock releases.Task { ... }orTask.detached { ... }call (not captured in alet/var).Task's trailing closure references at least one of thedefer-assigned identifiers.
Anything outside this shape does not warn, matching the issue's
false-negative-friendly design goal.
Testing
All triggering/non-triggering examples from the issue (plus a couple extra
covering the two-assignment and captured-
Taskcases) are included as therule's
triggeringExamples/nonTriggeringExamples, whichmake registerturns into generated unit tests.
Test plan
swift buildswift test --filter DeferBeforeUnstructuredTaskRuleGeneratedTestsswift test(full suite, 1089 tests passing)swiftlint lintagainst the repo itself (0 violations)swiftlintbinaryCloses #6619