pointfreeco / swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
https://www.pointfree.co/collections/composable-architecture
MIT License
12.35k stars 1.44k forks source link

Complier can't introduce a list of completions for `Effect<Action>` when using `BindingReducer()` in body #2386

Closed ValseLee closed 1 year ago

ValseLee commented 1 year ago

Description

Checklist

Expected behavior

Actual behavior

Steps to reproduce

  1. When using BindingReducer()

    struct ForIssue: Reducer {
    struct State: Equatable { var id: UUID }
    enum Action: Equatable, BindableAction {
    case binding(BindingAction<State>)
    case onButtonTapped
    }
    
    var body: some ReducerOf<Self> {
    /// if BindingReducer() exists in `body`,
    /// compiler can't introduce list of completions
    BindingReducer()
    
    Reduce { state, action in
      switch action {
      case .binding:
        return .none
    
      case .onButtonTapped:
        return .none
      }
    }
    }
    }

    image

  2. When stop using BindingReducer()

    struct ForIssue: Reducer {
    struct State: Equatable { var id: UUID }
    enum Action: Equatable, BindableAction {
    case binding(BindingAction<State>)
    case onButtonTapped
    }
    
    var body: some ReducerOf<Self> {
    /// if BindingReducer() exists in `body`,
    /// compiler can't introduce list of completions
    /// BindingReducer()
    
    Reduce { state, action in
      switch action {
      case .binding:
        return .none
    
      case .onButtonTapped:
        return .none
      }
    }
    }
    }

    image

  3. Reduce<State, Action> method completions are working as normal, if body has BidningReducer() or not. image

The Composable Architecture version information

beta 1.0.0

Destination operating system

iOS 16.2

Xcode version information

14.2 (14C18)

Swift Compiler version information

swift-driver version: 1.62.15 Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
Target: arm64-apple-macosx13.0
nivanchikov commented 1 year ago

@ValseLee can you try this tip by specifying the generics of your Reduce reducer: Reduce<State, Action> { state, action in … } as per this comment by @tgrapperon: https://github.com/pointfreeco/swift-composable-architecture/discussions/1666#discussioncomment-4212335

public var body: some ReducerOf<Self> {
  BindingReducer()

  Reduce<State, Action> { state, action in
    switch action {
      ... 
    }
  }
}

It generally helped me in similar situations.

ValseLee commented 1 year ago

@nivanchikov So.... I didn't try your solution before, but it is perfectly working! Thank you for your kind explanation with #1666 !

stephencelis commented 1 year ago

@ValseLee This was fixed in a later Xcode, as well. If you can upgrade from 14.2, which was released last year, to 14.3.1, this should be fixed without the need of those generics!

JeongAYoo commented 6 months ago

@stephencelis I'm working on Xcode 15.0.1 with TCA 1.9.2 (destination target is iOS 16) but I have the exact same problem described above... Is there something to check in project's build settings?

(Reduce<State, Action> { state, action in … } this works for me though)