Skip to content

Commit

Permalink
Address @shared sendability. (#3329)
Browse files Browse the repository at this point in the history
* Address @shared sendability.

* Undo UncheckedSendable<UserDefaults>.

* clean up

* wip

* drop AnySendable.

* wip

* Address `Effect.throttle` sendability (#3325)

* Address effect cancellation sendability (#3326)

* Address effect cancellation sendability

* fix

* wip

* wip

* Separate SendableDefaultSubscript from DefaultSubscript.

* fix test

* drop escaping

* switch on swift 6 language mode

* xcode 16

* update test

* wip

---------

Co-authored-by: Stephen Celis <stephen@stephencelis.com>
  • Loading branch information
mbrandonw and stephencelis authored Sep 6, 2024
1 parent 83ed123 commit 7c6fb26
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 113 deletions.
51 changes: 26 additions & 25 deletions .github/package.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "a84dfeef15185f26bd546eb430da9b0b1f23f5a08c6ac0f99b345a8de1564068",
"pins" : [
{
"identity" : "combine-schedulers",
Expand Down Expand Up @@ -32,26 +33,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-case-paths",
"state" : {
"revision" : "71344dd930fde41e8f3adafe260adcbb2fc2a3dc",
"version" : "1.5.4"
"revision" : "642e6aab8e03e5f992d9c83e38c5be98cfad5078",
"version" : "1.5.5"
}
},
{
"identity" : "swift-clocks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-clocks",
"state" : {
"revision" : "3581e280bf0d90c3fb9236fb23e75a5d8c46b533",
"version" : "1.0.4"
"revision" : "b9b24b69e2adda099a1fa381cda1eeec272d5b53",
"version" : "1.0.5"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections",
"state" : {
"revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
"version" : "1.1.2"
"revision" : "9bf03ff58ce34478e66aaee630e491823326fd06",
"version" : "1.1.3"
}
},
{
Expand All @@ -77,23 +78,23 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-dependencies",
"state" : {
"revision" : "d7472be6b3c89251ce4c0db07d32405b43426781",
"version" : "1.3.7"
"revision" : "3ef38bb702a1a2f39c7e19fc0578403b8ee52b17",
"version" : "1.3.9"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"location" : "https://github.com/swiftlang/swift-docc-plugin",
"state" : {
"revision" : "26ac5758409154cc448d7ab82389c520fa8a8247",
"version" : "1.3.0"
"revision" : "2eb22993b3dfd0c0d32729b357c8dabb6cd44680",
"version" : "1.4.2"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-symbolkit",
"location" : "https://github.com/swiftlang/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
Expand All @@ -113,55 +114,55 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-macro-testing",
"state" : {
"revision" : "a35257b7e9ce44e92636447003a8eeefb77b145c",
"version" : "0.5.1"
"revision" : "20c1a8f3b624fb5d1503eadcaa84743050c350f4",
"version" : "0.5.2"
}
},
{
"identity" : "swift-navigation",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-navigation",
"state" : {
"revision" : "47cfd149ed01223d14fc8e3f52ae27d3a35fe036",
"version" : "2.0.3"
"revision" : "e834b3760731160d7d448509ee6a1408c8582a6b",
"version" : "2.2.0"
}
},
{
"identity" : "swift-perception",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-perception",
"state" : {
"revision" : "1552c8f722ac256cc0b8daaf1a7073217d4fcdfb",
"version" : "1.3.4"
"revision" : "bc67aa8e461351c97282c2419153757a446ae1c9",
"version" : "1.3.5"
}
},
{
"identity" : "swift-snapshot-testing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
"state" : {
"revision" : "c097f955b4e724690f0fc8ffb7a6d4b881c9c4e3",
"version" : "1.17.2"
"revision" : "6d932a79e7173b275b96c600c86c603cf84f153c",
"version" : "1.17.4"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-syntax",
"state" : {
"revision" : "4c6cc0a3b9e8f14b3ae2307c5ccae4de6167ac2c",
"version" : "600.0.0-prerelease-2024-06-12"
"revision" : "515f79b522918f83483068d99c68daeb5116342d",
"version" : "600.0.0-prerelease-2024-09-04"
}
},
{
"identity" : "xctest-dynamic-overlay",
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state" : {
"revision" : "357ca1e5dd31f613a1d43320870ebc219386a495",
"version" : "1.2.2"
"revision" : "96beb108a57f24c8476ae1f309239270772b2940",
"version" : "1.2.5"
}
}
],
"version" : 2
"version" : 3
}
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ jobs:
runs-on: macos-14
strategy:
matrix:
xcode:
- 15.4
- 16_beta_6
config:
- debug
- release
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Select Xcode ${{ matrix.xcode }}
run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
- name: Build ${{ matrix.config }}
run: make CONFIG=${{ matrix.config }} build-all-platforms
- name: Run ${{ matrix.config }} tests
if: matrix.xcode == '15.4'
run: make CONFIG=${{ matrix.config }} test-library

# library-evolution:
Expand Down
7 changes: 4 additions & 3 deletions Examples/SyncUps/SyncUpsTests/AppFeatureTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import XCTest

final class AppFeatureTests: XCTestCase {
func testDetailEdit() async throws {
var syncUp = SyncUp.mock
let syncUp = SyncUp.mock
@Shared(.syncUps) var syncUps = [syncUp]
let store = await TestStore(initialState: AppFeature.State()) {
AppFeature()
Expand All @@ -21,8 +21,9 @@ final class AppFeatureTests: XCTestCase {
$0.path[id: 0]?.modify(\.detail) { $0.destination = .edit(SyncUpForm.State(syncUp: syncUp)) }
}

syncUp.title = "Blob"
await store.send(\.path[id:0].detail.destination.edit.binding.syncUp, syncUp) {
var newSyncUp = syncUp
newSyncUp.title = "Blob"
await store.send(\.path[id:0].detail.destination.edit.binding.syncUp, newSyncUp) {
$0.path[id: 0]?.modify(\.detail) {
$0.destination?.modify(\.edit) { $0.syncUp.title = "Blob" }
}
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ let package = Package(
)

#if compiler(>=6)
for target in package.targets where target.type != .system {
for target in package.targets where target.type != .system && target.type != .test {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings?.append(contentsOf: [
.enableExperimentalFeature("StrictConcurrency"),
Expand Down
97 changes: 97 additions & 0 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// swift-tools-version:6.0

import CompilerPluginSupport
import PackageDescription

let package = Package(
name: "swift-composable-architecture",
platforms: [
.iOS(.v13),
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v6),
],
products: [
.library(
name: "ComposableArchitecture",
targets: ["ComposableArchitecture"]
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-collections", from: "1.1.0"),
.package(url: "https://github.com/google/swift-benchmark", from: "0.1.0"),
.package(url: "https://github.com/pointfreeco/combine-schedulers", from: "1.0.2"),
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "1.5.4"),
.package(url: "https://github.com/pointfreeco/swift-concurrency-extras", from: "1.1.0"),
.package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.2"),
.package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.3.5"),
.package(url: "https://github.com/pointfreeco/swift-identified-collections", from: "1.1.0"),
.package(url: "https://github.com/pointfreeco/swift-macro-testing", from: "0.2.0"),
.package(url: "https://github.com/pointfreeco/swift-navigation", from: "2.1.0"),
.package(url: "https://github.com/pointfreeco/swift-perception", from: "1.3.4"),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.2.2"),
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.0.0"),
.package(url: "https://github.com/swiftlang/swift-syntax", "509.0.0"..<"601.0.0-prerelease"),
],
targets: [
.target(
name: "ComposableArchitecture",
dependencies: [
"ComposableArchitectureMacros",
.product(name: "CasePaths", package: "swift-case-paths"),
.product(name: "CombineSchedulers", package: "combine-schedulers"),
.product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"),
.product(name: "CustomDump", package: "swift-custom-dump"),
.product(name: "Dependencies", package: "swift-dependencies"),
.product(name: "DependenciesMacros", package: "swift-dependencies"),
.product(name: "IdentifiedCollections", package: "swift-identified-collections"),
.product(name: "IssueReporting", package: "xctest-dynamic-overlay"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Perception", package: "swift-perception"),
.product(name: "SwiftUINavigation", package: "swift-navigation"),
.product(name: "UIKitNavigation", package: "swift-navigation"),
],
resources: [
.process("Resources/PrivacyInfo.xcprivacy")
]
),
.testTarget(
name: "ComposableArchitectureTests",
dependencies: [
"ComposableArchitecture",
.product(name: "IssueReportingTestSupport", package: "xctest-dynamic-overlay"),
]
),
.macro(
name: "ComposableArchitectureMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
]
),
.testTarget(
name: "ComposableArchitectureMacrosTests",
dependencies: [
"ComposableArchitectureMacros",
.product(name: "MacroTesting", package: "swift-macro-testing"),
]
),
.executableTarget(
name: "swift-composable-architecture-benchmark",
dependencies: [
"ComposableArchitecture",
.product(name: "Benchmark", package: "swift-benchmark"),
]
),
],
swiftLanguageModes: [.v6]
)

for target in package.targets where target.type == .system || target.type == .test {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings?.append(contentsOf: [
.swiftLanguageMode(.v5),
.enableExperimentalFeature("StrictConcurrency"),
.enableUpcomingFeature("InferSendableFromCaptures")
])
}
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ public struct _PresentedID: Hashable, Sendable {

extension Task<Never, Never> {
internal static func _cancel(
id: some Hashable,
id: some Hashable & Sendable,
navigationID: NavigationIDPath
) {
withDependencies {
Expand All @@ -754,7 +754,7 @@ extension Effect {
}
}
internal static func _cancel(
id: some Hashable = _PresentedID(),
id: some Hashable & Sendable = _PresentedID(),
navigationID: NavigationIDPath
) -> Self {
withDependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
///
/// See the article <doc:SharingState> for more information, in particular the
/// <doc:SharingState#Custom-persistence> section.
public protocol PersistenceReaderKey<Value> {
public protocol PersistenceReaderKey<Value>: Sendable {
/// A type that can be loaded or subscribed to in an external system.
associatedtype Value
associatedtype Value: Sendable

/// A type representing the hashable identity of a persistence key.
associatedtype ID: Hashable = Self
Expand Down
Loading

0 comments on commit 7c6fb26

Please sign in to comment.