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.22k stars 1.42k forks source link

BindingAction equality changed in 0.55.0 #2270

Closed lukeredpath closed 1 year ago

lukeredpath commented 1 year ago

Description

I'm trying to upgrade to 0.55 and there seems to have been a change in the implementation of BindingAction<T> equality, because I have some tests that .receive a binding action which fail due to them not being equal.

Checklist

Expected behavior

When using store.receive(.set(\.$foo, "bar")) in a test, if that action is received the test should pass.

Actual behavior

The test fails, complaining that the actions were not equal although they have no differences.

On further inspection in the debugger, I set a breakpoint inside BindingAction.== and observed this in one of my tests:

(lldb) po rhs
▿ BindingAction<State>
  - keyPath : \State.$isFocused
  - set : (Function)
  ▿ value : AnySendable
    - base : true
  - valueIsEqualTo : (Function)

(lldb) po lhs.keyPath == rhs.keyPath
true

(lldb) po lhs.valueIsEqualTo(rhs.value)
false

(lldb) po lhs.value
▿ AnySendable
  - base : true

(lldb) po rhs.value
▿ AnySendable
  - base : true

Steps to reproduce

There's a demo of this problem here: https://gist.github.com/lukeredpath/96ac8bfea295f0b729408ecce694ca26

The Composable Architecture version information

0.55.0

Destination operating system

iOS 16

Xcode version information

Xcode 14.3

Swift Compiler version information

swift-driver version: 1.75.2 Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)
Target: arm64-apple-macosx13.0
lukeredpath commented 1 year ago

It looks like the issue is that the == implementation is passing the AnySendable into the valueIsEqualTo function but it is expecting the underlying base value.

  public static func == (lhs: Self, rhs: Self) -> Bool {
-    lhs.keyPath == rhs.keyPath && lhs.valueIsEqualTo(rhs.value)
+    lhs.keyPath == rhs.keyPath && lhs.valueIsEqualTo(rhs.value.base)
  }
lukeredpath commented 1 year ago

Ah, turns out this is fixed on main.

https://github.com/pointfreeco/swift-composable-architecture/commit/d74930b494dea3962372a590525e9a0ce0e92a67

Fixed by https://github.com/pointfreeco/swift-composable-architecture/pull/2248

Is there any chance of a 0.55.1 release with this fix please?