You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Audit and unwind tactical concurrency escape hatches from the Swift 6 migration #1198
Follow-up to #1192. The migration used @unchecked Sendable / nonisolated(unsafe) deliberately, each with a documented invariant. Most are permanent by design (the REST models under the HasReferences contract can't get checked conformances while they subclass NSObject), but several could become compiler-checked with modest refactors:
ArrivalDeparture.route/stop/trip (and other HasReferences conformers): convert post-loadReferences stored vars to private(set) per the plan doc's own recommendation, so the "read-only after handoff" contract is partially enforced.
AnalyticsOrchestrator.userDefaults (nonisolated(unsafe) let): could become checked if/when UserDefaults gains a Sendable annotation, or by routing reportingEnabled() through a Sendable wrapper.
DecodingErrorReporter._reportHandler (nonisolated(unsafe) + lock): a candidate for Mutex (iOS 18+) which is checked.
UncheckedSendableBox (OBAKit/Utilities): re-evaluate both MapKit call sites (MapRegionManager.handleMapFeatureSelection, MapItemViewModel.fetchScene) whenever the deployed Swift compiler floor rises — newer region analysis accepts the direct await and the boxes can be deleted.
AgencyAlertsStore notify methods use Task { @MainActor }, which doesn't guarantee FIFO relative to DispatchQueue.main.async work; no delegate currently depends on ordering, but note it if delegate contracts grow.
Icons.iconCache / other nonisolated(unsafe) NSCache statics: checked automatically once NSCache is annotated Sendable.
Rule of thumb from the plan: prefer deleting an escape hatch over re-justifying it whenever a toolchain or dependency update makes the checked form possible.
Looks like the first unwind slice already landed on `main` (`docs/swift6-escape-hatches.md`: `private(set)` on ArrivalDeparture/StopArrivals refs + `Mutex` for `DecodingErrorReporter`). Leaving the remaining hatches (UncheckedSendableBox, AnalyticsOrchestrator, Trip.route) for a later PR unless you want them bundled.
Activity
Tighten a few Swift 6 concurrency escape hatches
Borisserz commentedon Sep 4, 2026
Taking a small first slice of the concurrency-hatch audit (not the whole issue).
Borisserz commentedon Sep 4, 2026
Looks like the first unwind slice already landed on `main` (`docs/swift6-escape-hatches.md`: `private(set)` on ArrivalDeparture/StopArrivals refs + `Mutex` for `DecodingErrorReporter`). Leaving the remaining hatches (UncheckedSendableBox, AnalyticsOrchestrator, Trip.route) for a later PR unless you want them bundled.