Skip to content

Commit

Permalink
Existential any to protocol for Swift 6 (#3370)
Browse files Browse the repository at this point in the history
* Apply existential any to protocol for Swift 6

* Update Package@swift-6.0.swift

* Update Package.swift

* Apply any to Macro.Type

* Apply any for the rest

* Applying the any keyword internally for typealias in a _KeyPath

* Undoing accidental syntax

---------

Co-authored-by: Stephen Celis <stephen@stephencelis.com>
Co-authored-by: Stephen Celis <stephen.celis@gmail.com>
  • Loading branch information
3 people committed Sep 10, 2024
1 parent af07aa9 commit 71cfb1e
Show file tree
Hide file tree
Showing 44 changed files with 83 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct SharedStateNotifications {
@SharedReader(.screenshotCount) var screenshotCount = 0
}
enum Action {
case factResponse(Result<String, Error>)
case factResponse(Result<String, any Error>)
case onAppear
}
@Dependency(\.factClient) var factClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct EffectsBasics {
case decrementDelayResponse
case incrementButtonTapped
case numberFactButtonTapped
case numberFactResponse(Result<String, Error>)
case numberFactResponse(Result<String, any Error>)
}

@Dependency(\.continuousClock) var clock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct EffectsCancellation {
case cancelButtonTapped
case stepperChanged(Int)
case factButtonTapped
case factResponse(Result<String, Error>)
case factResponse(Result<String, any Error>)
}

@Dependency(\.factClient) var factClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct Refreshable {
enum Action {
case cancelButtonTapped
case decrementButtonTapped
case factResponse(Result<String, Error>)
case factResponse(Result<String, any Error>)
case incrementButtonTapped
case refresh
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct WebSocket {
case alert(PresentationAction<Alert>)
case connectButtonTapped
case messageToSendChanged(String)
case receivedSocketMessage(Result<WebSocketClient.Message, Error>)
case receivedSocketMessage(Result<WebSocketClient.Message, any Error>)
case sendButtonTapped
case sendResponse(didSucceed: Bool)
case webSocket(WebSocketClient.Action)
Expand Down Expand Up @@ -227,7 +227,7 @@ struct WebSocketClient {
var open: @Sendable (_ id: ID, _ url: URL, _ protocols: [String]) async -> AsyncStream<Action> = {
_, _, _ in .finished
}
var receive: @Sendable (_ id: ID) async throws -> AsyncStream<Result<Message, Error>>
var receive: @Sendable (_ id: ID) async throws -> AsyncStream<Result<Message, any Error>>
var send: @Sendable (_ id: ID, _ message: URLSessionWebSocketTask.Message) async throws -> Void
var sendPing: @Sendable (_ id: ID) async throws -> Void
}
Expand Down Expand Up @@ -295,7 +295,7 @@ extension WebSocketClient: DependencyKey {
try self.socket(id: id).cancel(with: closeCode, reason: reason)
}

func receive(id: ID) throws -> AsyncStream<Result<Message, Error>> {
func receive(id: ID) throws -> AsyncStream<Result<Message, any Error>> {
let socket = try self.socket(id: id)
return AsyncStream { continuation in
let task = Task {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ struct ScreenA {
case dismissButtonTapped
case incrementButtonTapped
case factButtonTapped
case factResponse(Result<String, Error>)
case factResponse(Result<String, any Error>)
}

@Dependency(\.dismiss) var dismiss
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation

@DependencyClient
struct DownloadClient {
var download: @Sendable (_ url: URL) -> AsyncThrowingStream<Event, Error> = { _ in .finished() }
var download: @Sendable (_ url: URL) -> AsyncThrowingStream<Event, any Error> = { _ in .finished() }

@CasePathable
enum Event: Equatable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct DownloadComponent {
enum Action {
case alert(PresentationAction<Alert>)
case buttonTapped
case downloadClient(Result<DownloadClient.Event, Error>)
case downloadClient(Result<DownloadClient.Event, any Error>)

@CasePathable
enum Alert {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct FavoritingState<ID: Hashable & Sendable>: Equatable {
enum FavoritingAction {
case alert(PresentationAction<Alert>)
case buttonTapped
case response(Result<Bool, Error>)
case response(Result<Bool, any Error>)

enum Alert: Equatable {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import XCTest
final class WebSocketTests: XCTestCase {
func testWebSocketHappyPath() async {
let actions = AsyncStream.makeStream(of: WebSocketClient.Action.self)
let messages = AsyncStream.makeStream(of: Result<WebSocketClient.Message, Error>.self)
let messages = AsyncStream.makeStream(of: Result<WebSocketClient.Message, any Error>.self)

let store = await TestStore(initialState: WebSocket.State()) {
WebSocket()
Expand Down Expand Up @@ -57,7 +57,7 @@ final class WebSocketTests: XCTestCase {

func testWebSocketSendFailure() async {
let actions = AsyncStream.makeStream(of: WebSocketClient.Action.self)
let messages = AsyncStream.makeStream(of: Result<WebSocketClient.Message, Error>.self)
let messages = AsyncStream.makeStream(of: Result<WebSocketClient.Message, any Error>.self)

let store = await TestStore(initialState: WebSocket.State()) {
WebSocket()
Expand Down
4 changes: 2 additions & 2 deletions Examples/Search/Search/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ struct Search {
}

enum Action {
case forecastResponse(GeocodingSearch.Result.ID, Result<Forecast, Error>)
case forecastResponse(GeocodingSearch.Result.ID, Result<Forecast, any Error>)
case searchQueryChanged(String)
case searchQueryChangeDebounced
case searchResponse(Result<GeocodingSearch, Error>)
case searchResponse(Result<GeocodingSearch, any Error>)
case searchResultTapped(GeocodingSearch.Result)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extension SpeechClient: DependencyKey {
private actor Speech {
var audioEngine: AVAudioEngine? = nil
var recognitionTask: SFSpeechRecognitionTask? = nil
var recognitionContinuation: AsyncThrowingStream<SpeechRecognitionResult, Error>.Continuation?
var recognitionContinuation: AsyncThrowingStream<SpeechRecognitionResult, any Error>.Continuation?

func finishTask() {
self.audioEngine?.stop()
Expand All @@ -37,7 +37,7 @@ private actor Speech {

func startTask(
request: UncheckedSendable<SFSpeechAudioBufferRecognitionRequest>
) -> AsyncThrowingStream<SpeechRecognitionResult, Error> {
) -> AsyncThrowingStream<SpeechRecognitionResult, any Error> {
let request = request.wrappedValue

return AsyncThrowingStream { continuation in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct SpeechRecognition {
enum Action {
case alert(PresentationAction<Alert>)
case recordButtonTapped
case speech(Result<String, Error>)
case speech(Result<String, any Error>)
case speechRecognizerAuthorizationStatusResponse(SFSpeechRecognizerAuthorizationStatus)

enum Alert: Equatable {}
Expand Down
4 changes: 2 additions & 2 deletions Examples/SyncUps/SyncUps/Dependencies/SpeechRecognizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ private actor Speech {
private var audioEngine: AVAudioEngine? = nil
private var recognitionTask: SFSpeechRecognitionTask? = nil
private var recognitionContinuation:
AsyncThrowingStream<SpeechRecognitionResult, Error>.Continuation?
AsyncThrowingStream<SpeechRecognitionResult, any Error>.Continuation?

func startTask(
request: SFSpeechAudioBufferRecognitionRequest
) -> AsyncThrowingStream<SpeechRecognitionResult, Error> {
) -> AsyncThrowingStream<SpeechRecognitionResult, any Error> {
AsyncThrowingStream { continuation in
self.recognitionContinuation = continuation
let audioSession = AVAudioSession.sharedInstance()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public struct Login: Sendable {

public enum Action: Sendable, ViewAction {
case alert(PresentationAction<Alert>)
case loginResponse(Result<AuthenticationResponse, Error>)
case loginResponse(Result<AuthenticationResponse, any Error>)
case twoFactor(PresentationAction<TwoFactor.Action>)
case view(View)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public struct TwoFactor: Sendable {

public enum Action: Sendable, ViewAction {
case alert(PresentationAction<Alert>)
case twoFactorResponse(Result<AuthenticationResponse, Error>)
case twoFactorResponse(Result<AuthenticationResponse, any Error>)
case view(View)

public enum Alert: Equatable, Sendable {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Dependencies

extension AudioPlayerClient: DependencyKey {
static let liveValue = Self { url in
let stream = AsyncThrowingStream<Bool, Error> { continuation in
let stream = AsyncThrowingStream<Bool, any Error> { continuation in
do {
let delegate = try Delegate(
url: url,
Expand Down Expand Up @@ -48,7 +48,7 @@ private final class Delegate: NSObject, AVAudioPlayerDelegate, Sendable {
self.didFinishPlaying(flag)
}

func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: (any Error)?) {
self.decodeErrorDidOccur(error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private actor AudioRecorder {
func start(url: URL) async throws -> Bool {
self.stop()

let stream = AsyncThrowingStream<Bool, Error> { continuation in
let stream = AsyncThrowingStream<Bool, any Error> { continuation in
do {
self.delegate = Delegate(
didFinishRecording: { flag in
Expand Down Expand Up @@ -83,11 +83,11 @@ private actor AudioRecorder {

private final class Delegate: NSObject, AVAudioRecorderDelegate, Sendable {
let didFinishRecording: @Sendable (Bool) -> Void
let encodeErrorDidOccur: @Sendable (Error?) -> Void
let encodeErrorDidOccur: @Sendable ((any Error)?) -> Void

init(
didFinishRecording: @escaping @Sendable (Bool) -> Void,
encodeErrorDidOccur: @escaping @Sendable (Error?) -> Void
encodeErrorDidOccur: @escaping @Sendable ((any Error)?) -> Void
) {
self.didFinishRecording = didFinishRecording
self.encodeErrorDidOccur = encodeErrorDidOccur
Expand All @@ -97,7 +97,7 @@ private final class Delegate: NSObject, AVAudioRecorderDelegate, Sendable {
self.didFinishRecording(flag)
}

func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: (any Error)?) {
self.encodeErrorDidOccur(error)
}
}
4 changes: 2 additions & 2 deletions Examples/VoiceMemos/VoiceMemos/RecordingMemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct RecordingMemo {
}

enum Action: Sendable {
case audioRecorderDidFinish(Result<Bool, Error>)
case audioRecorderDidFinish(Result<Bool, any Error>)
case delegate(Delegate)
case finalRecordingTime(TimeInterval)
case onTask
Expand All @@ -26,7 +26,7 @@ struct RecordingMemo {

@CasePathable
enum Delegate: Sendable {
case didFinish(Result<State, Error>)
case didFinish(Result<State, any Error>)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Examples/VoiceMemos/VoiceMemos/VoiceMemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct VoiceMemo {
}

enum Action {
case audioPlayerClient(Result<Bool, Error>)
case audioPlayerClient(Result<Bool, any Error>)
case delegate(Delegate)
case playButtonTapped
case timerUpdated(TimeInterval)
Expand Down
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ let package = Package(
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings?.append(contentsOf: [
.enableExperimentalFeature("StrictConcurrency"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("InferSendableFromCaptures"),
])
}
Expand Down
8 changes: 7 additions & 1 deletion Package@swift-6.0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,14 @@ let package = Package(
swiftLanguageModes: [.v6]
)

for target in package.targets where target.type == .system || target.type == .test {
for target in package.targets {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings?.append(contentsOf: [
.enableUpcomingFeature("ExistentialAny"),
])
}

for target in package.targets where target.type == .system || target.type == .test {
target.swiftSettings?.append(contentsOf: [
.swiftLanguageMode(.v5),
.enableExperimentalFeature("StrictConcurrency"),
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComposableArchitecture/Effect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ extension Effect {
public static func run(
priority: TaskPriority? = nil,
operation: @escaping @Sendable (_ send: Send<Action>) async throws -> Void,
catch handler: (@Sendable (_ error: Error, _ send: Send<Action>) async -> Void)? = nil,
catch handler: (@Sendable (_ error: any Error, _ send: Send<Action>) async -> Void)? = nil,
fileID: StaticString = #fileID,
filePath: StaticString = #filePath,
line: UInt = #line,
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComposableArchitecture/Effects/Animation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private struct TransactionPublisher<Upstream: Publisher>: Publisher {
self.transaction = transaction
}

func receive(subscription: Subscription) {
func receive(subscription: any Subscription) {
self.downstream.receive(subscription: subscription)
}

Expand Down
8 changes: 4 additions & 4 deletions Sources/ComposableArchitecture/Effects/Cancellation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ extension Effect {
) async rethrows -> T {
@Dependency(\.navigationIDPath) var navigationIDPath

let (cancellable, task): (AnyCancellable, Task<T, Error>) =
let (cancellable, task): (AnyCancellable, Task<T, any Error>) =
_cancellationCancellables
.withValue {
if cancelInFlight {
Expand All @@ -191,7 +191,7 @@ extension Effect {
do {
return try await task.cancellableValue
} catch {
return try Result<T, Error>.failure(error)._rethrowGet()
return try Result<T, any Error>.failure(error)._rethrowGet()
}
}
#else
Expand All @@ -203,7 +203,7 @@ extension Effect {
) async rethrows -> T {
@Dependency(\.navigationIDPath) var navigationIDPath

let (cancellable, task): (AnyCancellable, Task<T, Error>) =
let (cancellable, task): (AnyCancellable, Task<T, any Error>) =
_cancellationCancellables
.withValue {
if cancelInFlight {
Expand All @@ -222,7 +222,7 @@ extension Effect {
do {
return try await task.cancellableValue
} catch {
return try Result<T, Error>.failure(error)._rethrowGet()
return try Result<T, any Error>.failure(error)._rethrowGet()
}
}
#endif
Expand Down
8 changes: 4 additions & 4 deletions Sources/ComposableArchitecture/Effects/TaskResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
///
/// This type is needed because Swift's concurrency tools can only express untyped errors, such as
/// `async` functions and `AsyncSequence`, and so their output can realistically only be bridged to
/// `Result<_, Error>`. However, `Result<_, Error>` is never `Equatable` since `Error` is not
/// `Result<_, any Error>`. However, `Result<_, any Error>` is never `Equatable` since `Error` is not
/// `Equatable`, and equatability is very important for testing in the Composable Architecture. By
/// defining our own type we get the ability to recover equatability in most situations.
///
Expand Down Expand Up @@ -129,7 +129,7 @@ public enum TaskResult<Success: Sendable>: Sendable {
case success(Success)

/// A failure, storing an error.
case failure(Error)
case failure(any Error)

/// Creates a new task result by evaluating an async throwing closure, capturing the returned
/// value as a success, or any thrown error as a failure.
Expand Down Expand Up @@ -226,7 +226,7 @@ extension TaskResult: CasePathable {
)
}

public var failure: AnyCasePath<TaskResult, Error> {
public var failure: AnyCasePath<TaskResult, any Error> {
AnyCasePath(
embed: { .failure($0) },
extract: {
Expand All @@ -238,7 +238,7 @@ extension TaskResult: CasePathable {
}
}

extension Result where Success: Sendable, Failure == Error {
extension Result where Success: Sendable, Failure == any Error {
/// Transforms a `TaskResult` into a `Result`.
///
/// - Parameter result: A task result.
Expand Down
Loading

0 comments on commit 71cfb1e

Please sign in to comment.