Files
Doug 33e7c1a819 Add Swift Concurrency Pro skill to the project. (#5662)
Installed for Copilot with `gh skill install` and manually created a symlink for Claude to access all Copilot skills.
2026-05-29 12:47:48 +01:00

48 lines
2.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hotspots
Search targets for concurrency review. When any of these appear in code, inspect carefully using the referenced rules.
## `DispatchQueue`
In app-level code, `DispatchQueue.main.async`, `DispatchQueue.global()`, and custom serial queues usually have a Swift concurrency equivalent – see `interop.md`. However, GCD can still be appropriate in low-level libraries, framework interop, and performance-critical synchronous sections where queues or locks are the right tool. Check the context carefully before flagging.
## `Task.detached`
Rarely correct. Usually means the author wanted background execution but should have used `@concurrent` (Swift 6.2) or a task group. Check whether shedding actor isolation and priority is truly intentional. See `unstructured.md`.
## `Task {}` inside a loop
Frequently a bad idea – evaluate whether it should be a task group instead. See `structured.md`.
## `withCheckedContinuation` / `withCheckedThrowingContinuation`
Audit every code path to ensure the continuation is resumed exactly once. Watch for early returns, thrown errors, and callbacks that might never fire. See `bridging.md`.
## `AsyncStream` (closure-based initializer)
Prefer the modern `AsyncStream.makeStream(of:)` factory. If using the closure form, verify the continuation is finished in all cleanup paths. See `async-streams.md`.
## `@unchecked Sendable`
Should be very rare. Check whether the type actually provides thread safety (internal locking, immutability). If it was added just to silence a compiler error, the real fix is usually an actor or value type. Check whether Swift 6 region-based isolation makes it unnecessary. See `bridging.md`.
## `MainActor.run {}`
Often unnecessary. If the surrounding code is already `@MainActor` (explicitly or via default isolation), this is a no-op. If it's used to hop to the main actor from a background context, check whether the function should just be `@MainActor` instead.
## Actors
Check for reentrancy bugs: any method that reads state, awaits, then writes state is suspect. See `actors.md` and `bug-patterns.md`.
## Force unwraps after `await` inside actors
A `!` on actor state after an `await` is a prime target for a latent crash, because another caller may have set the value to `nil` during the suspension. See `bug-patterns.md`.