From 90c203de7d0ec382069a780cd78c077bb76d14a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5ns=20Bernhardt?= Date: Mon, 14 Sep 2026 14:29:42 +0200 Subject: [PATCH] Make the test suite compile on Swift 6.4: explicit capture lists for onCancel closures Swift 6.4's region-isolation checker rejects two `withTaskCancellationHandler` call sites where the `onCancel` closure implicitly captured a `LockIsolated` counter also used by the enclosing `model.task { }` closure. An explicit `[$count]` / `[$cancelCount]` capture list gives `onCancel` its own copy of the Sendable reference. No behavioural change. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 4 ++++ Tests/SwiftModelTests/CancellationTests.swift | 2 +- Tests/SwiftModelTests/InheritCancellationContextTests.swift | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa6b9e0a..ab85d4a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes are documented here. The format follows [Keep a Changelog](h ## [Unreleased] +### Tests + +- **The test suite compiles on Swift 6.4 (Xcode 27.0).** 6.4's region-isolation checker rejects two `withTaskCancellationHandler` call sites in `CancellationTests` and `InheritCancellationContextTests` ("passing closure as a `sending` parameter risks causing data races"): the `onCancel` closure implicitly captured a `LockIsolated` counter that the enclosing `model.task { }` closure also uses, and the checker merges the two closures' regions. An explicit `[$count]` / `[$cancelCount]` capture list gives `onCancel` its own copy of the (Sendable) reference and the checker is satisfied. No behavioural change; the library itself already compiled on 6.4 once 1.0.19 landed. + --- ## [1.0.19] — Swift 6.4 `@Model` closure-property compiler crash fix diff --git a/Tests/SwiftModelTests/CancellationTests.swift b/Tests/SwiftModelTests/CancellationTests.swift index bb85f559..0e9b2d00 100644 --- a/Tests/SwiftModelTests/CancellationTests.swift +++ b/Tests/SwiftModelTests/CancellationTests.swift @@ -103,7 +103,7 @@ struct CancellationTests { // Using a long sleep so the task cannot complete naturally before being cancelled. await inHandler.send(()) try await Task.sleep(nanoseconds: nanosPerSecond * 60) - } onCancel: { + } onCancel: { [$count] in $count.wrappedValue += 1 } $count.wrappedValue += 5 diff --git a/Tests/SwiftModelTests/InheritCancellationContextTests.swift b/Tests/SwiftModelTests/InheritCancellationContextTests.swift index 3db6c43c..5a6cbfcb 100644 --- a/Tests/SwiftModelTests/InheritCancellationContextTests.swift +++ b/Tests/SwiftModelTests/InheritCancellationContextTests.swift @@ -45,7 +45,7 @@ struct InheritCancellationContextTests { // This guarantees cancelAll below fires onCancel synchronously. await inHandler.send(()) try await Task.sleep(nanoseconds: nanosPerSecond * 60) - } onCancel: { + } onCancel: { [$cancelCount] in $cancelCount.wrappedValue += 1 } } catch: { _ in }