Swift 6 updates (#3379)

* Swift 6 updates

  - Soft-deprecate `_SynthesizedConformance` now that Xcode 16 has fixed
    this bug.
    - Update docs accordingly.

  - Document Xcode 16 macro gotcha around custom build configuration
    names.

* wip
This commit is contained in:
Stephen Celis
2024-09-12 14:11:05 -07:00
committed by GitHub
parent 8013f1a72a
commit f1af33763e
35 changed files with 112 additions and 101 deletions

View File

@@ -3,11 +3,12 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
}
// ...
}
extension SyncUpDetail.Destination.State: Equatable {}
struct SyncUpDetailView: View {
// ...

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -14,6 +14,7 @@ struct SyncUpDetail {
}
// ...
}
extension SyncUpDetail.Destination.State: Equatable {}
struct SyncUpDetailView: View {
// ...

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -78,6 +78,7 @@ struct SyncUpDetail {
.ifLet(\.$alert, action: \.alert)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -79,6 +79,7 @@ struct SyncUpDetail {
.ifLet(\.$alert, action: \.alert)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -77,6 +77,7 @@ struct SyncUpDetail {
.ifLet(\.$alert, action: \.alert)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -73,6 +73,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -70,6 +70,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -67,6 +67,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -67,6 +67,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -65,6 +65,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -64,6 +64,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -65,6 +65,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Action.Alert {
static let deleteSyncUp = Self {

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct SyncUpDetail {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case alert(AlertState<Alert>)
case edit(SyncUpForm)
@@ -65,6 +65,7 @@ struct SyncUpDetail {
.ifLet(\.$destination, action: \.destination)
}
}
extension SyncUpDetail.Destination.State: Equatable {}
extension AlertState where Action == SyncUpDetail.Destination.Alert {
static let deleteSyncUp = Self {

View File

@@ -368,10 +368,7 @@
> Important: As we have seen it is important for `State` types to be `Equatable` for
testing, and so we are proactively making the `State` type generated for the `Destination`
reducer equatable via the `state` argument of
``ComposableArchitecture/Reducer(state:action:)``. See the article
<doc:Reducer#Circular-reference-errors> for more information of why this is the necessary
way to make `State` equatable.
reducer equatable _via_ extension.
> Note: We have collapsed the implementation of `SyncUpDetail` and `SyncUpDetailView` in
> this code snippet.

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct AppFeature {
@Reducer(state: .equatable)
@Reducer
enum Path {
case detail(SyncUpDetail)
}
@@ -27,3 +27,4 @@ struct AppFeature {
}
}
}
extension AppFeature.Path.State: Equatable {}

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct AppFeature {
@Reducer(state: .equatable)
@Reducer
enum Path {
case detail(SyncUpDetail)
}
@@ -30,3 +30,4 @@ struct AppFeature {
}
}
}
extension AppFeature.Path.State: Equatable {}

View File

@@ -3,7 +3,7 @@ import SwiftUI
@Reducer
struct AppFeature {
@Reducer(state: .equatable)
@Reducer
enum Path {
case detail(SyncUpDetail)
}
@@ -31,3 +31,4 @@ struct AppFeature {
.forEach(\.path, action: \.path)
}
}
extension AppFeature.Path.State: Equatable {}

View File

@@ -92,11 +92,8 @@
Update the `path` variable to hold onto ``ComposableArchitecture/StackState`` of
`Path.State`.
> Important: In order to maintain `State`'s `Equatable`, we must conform `Path` to be
> `Equatable` as well. While this would typically be done with an extension, a Swift
> compiler bug prevents this, so the ``ComposableArchitecture/Reducer(state:action:)`` macro
> can generate this conformance for you by specifying the `state` parameter. See the article
> <doc:Reducer#Circular-reference-errors> for more.
> Important: In order to maintain `State`'s `Equatable`, we must conform `Path.State` to be
> `Equatable` as well.
@Code(name: "App.swift", file: SyncUpDetailNavigation-01-code-0006.swift)
}

View File

@@ -1,7 +1,8 @@
extension ContactsFeature {
@Reducer(state: .equatable)
@Reducer
enum Destination {
case addContact(AddContactFeature)
case alert(AlertState<ContactsFeature.Action.Alert>)
}
}
extension ContactsFeature.Destination.State: Equatable {}

View File

@@ -160,13 +160,8 @@
is no longer `Equatable`. This is happening because `Destination.State` is not `Equatable`,
and that type is generated by the [`@Reducer`](<doc:ComposableArchitecture/Reducer()>) macro.
Due to a bug in the Swift compiler it is not possible to extend `Destination.State` to be
`Equatable` yourself, and so there is an argument you can provide
``ComposableArchitecture/Reducer()`` in order to apply the protocol conformance.
@Step {
Use the `state` argument of ``ComposableArchitecture/Reducer(state:action:)`` to tell the
macro to apply an `Equatable` conformance to `Destination.State`.
Extend the macro-generated `Destination.State` to apply an `Equatable` conformance.
@Code(name: "ContactsFeatures.swift", file: 02-02-02-code-0004.swift, previousFile: 02-02-02-code-0004-previous.swift)
}