Skip to content

Commit

Permalink
Swift Language Support: Drop <5.9 (#3185)
Browse files Browse the repository at this point in the history
* Swift Language Support: Drop <5.9

* wip

* wip

* wip

* wip

* wip
  • Loading branch information
stephencelis authored Jun 19, 2024
1 parent 53bc869 commit bc8f27b
Show file tree
Hide file tree
Showing 64 changed files with 6,946 additions and 7,134 deletions.
30 changes: 15 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,54 +24,54 @@ jobs:
- release
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Build ${{ matrix.config }}
run: make CONFIG=${{ matrix.config }} build-all-platforms
- name: Run ${{ matrix.config }} tests
run: make CONFIG=${{ matrix.config }} test-library

library-evolution:
name: Library (evolution)
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Build for library evolution
run: make build-for-library-evolution

library-compatibility:
name: Library (Swift 5.7.1)
runs-on: macos-12
name: Library (Swift 5.9)
runs-on: macos-14
strategy:
matrix:
config:
- debug
- release
steps:
- uses: actions/checkout@v4
- name: Select Xcode 14.1
run: sudo xcode-select -s /Applications/Xcode_14.1.app
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Build ${{ matrix.config }}
run: swift build -c ${{ matrix.config }}

benchmarks:
name: Benchmarks
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Run benchmark
run: make benchmark

examples:
name: Examples
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Run tests
run: make test-examples
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ struct CityMap {
var downloadAlert: AlertState<DownloadComponent.Action.Alert>?
var downloadMode: Mode

var id: UUID { self.download.id }
var id: UUID { download.id }

var downloadComponent: DownloadComponent.State {
get {
DownloadComponent.State(
alert: self.downloadAlert,
id: self.download.id,
mode: self.downloadMode,
url: self.download.downloadVideoUrl
alert: downloadAlert,
id: download.id,
mode: downloadMode,
url: download.downloadVideoUrl
)
}
set {
self.downloadAlert = newValue.alert
self.downloadMode = newValue.mode
downloadAlert = newValue.alert
downloadMode = newValue.mode
}
}

Expand Down Expand Up @@ -80,10 +80,10 @@ struct CityMapRowView: View {
let store: StoreOf<CityMap>

var body: some View {
WithViewStore(self.store, observe: { $0 }) { viewStore in
WithViewStore(store, observe: { $0 }) { viewStore in
HStack {
NavigationLink(
destination: CityMapDetailView(store: self.store)
destination: CityMapDetailView(store: store)
) {
HStack {
Image(systemName: "map")
Expand All @@ -94,7 +94,7 @@ struct CityMapRowView: View {
Spacer()

DownloadComponentView(
store: self.store.scope(state: \.downloadComponent, action: \.downloadComponent)
store: store.scope(state: \.downloadComponent, action: \.downloadComponent)
)
.padding(.trailing, 8)
}
Expand All @@ -107,7 +107,7 @@ struct CityMapDetailView: View {
let store: StoreOf<CityMap>

var body: some View {
WithViewStore(self.store, observe: { $0 }) { viewStore in
WithViewStore(store, observe: { $0 }) { viewStore in
VStack(spacing: 32) {
Text(viewStore.download.blurb)

Expand All @@ -123,7 +123,7 @@ struct CityMapDetailView: View {
Spacer()

DownloadComponentView(
store: self.store.scope(state: \.downloadComponent, action: \.downloadComponent)
store: store.scope(state: \.downloadComponent, action: \.downloadComponent)
)
}

Expand Down Expand Up @@ -160,7 +160,7 @@ struct CitiesView: View {
Section {
AboutView(readMe: readMe)
}
ForEachStore(self.store.scope(state: \.cityMaps, action: \.cityMaps)) { cityMapStore in
ForEachStore(store.scope(state: \.cityMaps, action: \.cityMaps)) { cityMapStore in
CityMapRowView(store: cityMapStore)
.buttonStyle(.borderless)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ enum LogConfiguration {
case unordered
}

extension Snapshotting where Value == String, Format == String {
extension Snapshotting<String, String> {
fileprivate static nonisolated(unsafe) let _lines = Snapshotting(
pathExtension: "txt",
diffing: Diffing(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public enum Player: Equatable, Sendable {
}
}

extension Three where Element == Three<Player?> {
extension Three<Three<Player?>> {
public static let empty = Self(
.init(nil, nil, nil),
.init(nil, nil, nil),
Expand Down
2 changes: 1 addition & 1 deletion Examples/Todos/Todos/Todos.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ struct AppView: View {
}
}

extension IdentifiedArray where ID == Todo.State.ID, Element == Todo.State {
extension IdentifiedArrayOf<Todo.State> {
static let mock: Self = [
Todo.State(
description: "Check Mail",
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
CONFIG = debug
PLATFORM_IOS = iOS Simulator,id=$(call udid_for,iOS 17.2,iPhone \d\+ Pro [^M])
PLATFORM_IOS = iOS Simulator,id=$(call udid_for,iOS 17.5,iPhone \d\+ Pro [^M])
PLATFORM_MACOS = macOS
PLATFORM_MAC_CATALYST = macOS,variant=Mac Catalyst
PLATFORM_TVOS = tvOS Simulator,id=$(call udid_for,tvOS 17.2,TV)
PLATFORM_VISIONOS = visionOS Simulator,id=$(call udid_for,visionOS 1.0,Vision)
PLATFORM_WATCHOS = watchOS Simulator,id=$(call udid_for,watchOS 10.2,Watch)
PLATFORM_TVOS = tvOS Simulator,id=$(call udid_for,tvOS 17.5,TV)
PLATFORM_VISIONOS = visionOS Simulator,id=$(call udid_for,visionOS 1.2,Vision)
PLATFORM_WATCHOS = watchOS Simulator,id=$(call udid_for,watchOS 10.5,Watch)

default: test-all

Expand Down
4 changes: 2 additions & 2 deletions Sources/ComposableArchitecture/Effect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ extension Effect {
/// - Parameter effects: A sequence of effects.
/// - Returns: A new effect
@inlinable
public static func merge<S: Sequence>(_ effects: S) -> Self where S.Element == Self {
public static func merge(_ effects: some Sequence<Self>) -> Self {
effects.reduce(.none) { $0.merge(with: $1) }
}

Expand Down Expand Up @@ -289,7 +289,7 @@ extension Effect {
/// - Parameter effects: A collection of effects.
/// - Returns: A new effect
@inlinable
public static func concatenate<C: Collection>(_ effects: C) -> Self where C.Element == Self {
public static func concatenate(_ effects: some Collection<Self>) -> Self {
effects.reduce(.none) { $0.concatenate(with: $1) }
}

Expand Down
3 changes: 1 addition & 2 deletions Sources/ComposableArchitecture/Effects/Animation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ private struct TransactionPublisher<Upstream: Publisher>: Publisher {
var upstream: Upstream
var transaction: Transaction

func receive<S: Combine.Subscriber>(subscriber: S)
where S.Input == Output, S.Failure == Failure {
func receive(subscriber: some Combine.Subscriber<Upstream.Output, Upstream.Failure>) {
let conduit = Subscriber(downstream: subscriber, transaction: self.transaction)
self.upstream.receive(subscriber: conduit)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComposableArchitecture/Effects/Cancellation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public func withTaskCancellation<ID: Hashable, T: Sendable>(
}
}

extension Task where Success == Never, Failure == Never {
extension Task<Never, Never> {
/// Cancel any currently in-flight operation with the given identifier.
///
/// - Parameter id: An identifier.
Expand Down
17 changes: 5 additions & 12 deletions Sources/ComposableArchitecture/Effects/Publisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@ extension Effect {
///
/// - Parameter createPublisher: The closure to execute when the effect is performed.
/// - Returns: An effect wrapping a Combine publisher.
public static func publisher<P: Publisher>(_ createPublisher: () -> P) -> Self
where P.Output == Action, P.Failure == Never {
Self(
operation: .publisher(
createPublisher().eraseToAnyPublisher()
)
)
public static func publisher(_ createPublisher: () -> some Publisher<Action, Never>) -> Self {
Self(operation: .publisher(createPublisher().eraseToAnyPublisher()))
}
}

Expand All @@ -25,14 +20,12 @@ public struct _EffectPublisher<Action>: Publisher {
self.effect = effect
}

public func receive<S: Combine.Subscriber>(
subscriber: S
) where S.Input == Action, S.Failure == Failure {
self.publisher.subscribe(subscriber)
public func receive(subscriber: some Combine.Subscriber<Action, Failure>) {
publisher.subscribe(subscriber)
}

private var publisher: AnyPublisher<Action, Failure> {
switch self.effect.operation {
switch effect.operation {
case .none:
return Empty().eraseToAnyPublisher()
case let .publisher(publisher):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final class CurrentValueRelay<Output>: Publisher {
self.currentValue = value
}

func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Never {
func receive(subscriber: some Subscriber<Output, Never>) {
let subscription = Subscription(downstream: AnySubscriber(subscriber))
self.subscriptions.append(subscription)
subscriber.receive(subscription: subscription)
Expand All @@ -32,8 +32,7 @@ final class CurrentValueRelay<Output>: Publisher {
}

extension CurrentValueRelay {
final class Subscription<Downstream: Subscriber>: Combine.Subscription
where Downstream.Input == Output, Downstream.Failure == Failure {
final class Subscription<Downstream: Subscriber<Output, Failure>>: Combine.Subscription {
private var demandBuffer: DemandBuffer<Downstream>?

init(downstream: Downstream) {
Expand Down
42 changes: 15 additions & 27 deletions Sources/ComposableArchitecture/Internal/EphemeralState.swift
Original file line number Diff line number Diff line change
@@ -1,37 +1,25 @@
@_spi(Reflection) import CasePaths

#if swift(>=5.8)
/// Loosely represents features that are only briefly shown and the first time they are interacted
/// with they are dismissed. Such features do not manage any behavior on the inside.
///
/// Alerts and confirmation dialogs are examples of this kind of state.
@_documentation(visibility:public)
public protocol _EphemeralState<Action> {
associatedtype Action
static var actionType: Any.Type { get }
}
#else
public protocol _EphemeralState<Action> {
associatedtype Action
static var actionType: Any.Type { get }
}
#endif
/// Loosely represents features that are only briefly shown and the first time they are interacted
/// with they are dismissed. Such features do not manage any behavior on the inside.
///
/// Alerts and confirmation dialogs are examples of this kind of state.
@_documentation(visibility:public)
public protocol _EphemeralState<Action> {
associatedtype Action
static var actionType: Any.Type { get }
}

extension _EphemeralState {
public static var actionType: Any.Type { Action.self }
}

#if swift(>=5.8)
@_documentation(visibility:private)
extension AlertState: _EphemeralState {}
@_documentation(visibility:private)
@available(iOS 13, macOS 12, tvOS 13, watchOS 6, *)
extension ConfirmationDialogState: _EphemeralState {}
#else
extension AlertState: _EphemeralState {}
@available(iOS 13, macOS 12, tvOS 13, watchOS 6, *)
extension ConfirmationDialogState: _EphemeralState {}
#endif
@_documentation(visibility:private)
extension AlertState: _EphemeralState {}

@_documentation(visibility:private)
@available(iOS 13, macOS 12, tvOS 13, watchOS 6, *)
extension ConfirmationDialogState: _EphemeralState {}

@usableFromInline
func ephemeralType<State>(of state: State) -> (any _EphemeralState.Type)? {
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComposableArchitecture/Internal/Locking.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

extension UnsafeMutablePointer where Pointee == os_unfair_lock_s {
extension UnsafeMutablePointer<os_unfair_lock_s> {
@inlinable @discardableResult
func sync<R>(_ work: () -> R) -> R {
os_unfair_lock_lock(self)
Expand Down
12 changes: 4 additions & 8 deletions Sources/ComposableArchitecture/Internal/RuntimeWarnings.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import Foundation

extension Notification.Name {
#if swift(>=5.8)
@_documentation(visibility:private)
@available(*, deprecated, renamed: "_runtimeWarning")
public static let runtimeWarning = Self("ComposableArchitecture.runtimeWarning")
#else
@available(*, deprecated, renamed: "_runtimeWarning")
public static let runtimeWarning = Self("ComposableArchitecture.runtimeWarning")
#endif
@_documentation(visibility:private)
@available(*, deprecated, renamed: "_runtimeWarning")
public static let runtimeWarning = Self("ComposableArchitecture.runtimeWarning")

/// A notification that is posted when a runtime warning is emitted.
public static let _runtimeWarning = Self("ComposableArchitecture.runtimeWarning")
}
Expand Down
Loading

0 comments on commit bc8f27b

Please sign in to comment.