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

Setter for 'subscript(dynamicMember:)' is unavailable #3246

Closed omarzl closed 1 month ago

omarzl commented 1 month ago

Description

Error presented when writing a line in a test: $0.destination?.addContact?.contact.name = "Blob Jr." after following the tutorial https://pointfreeco.github.io/swift-composable-architecture/main/tutorials/composablearchitecture/02-03-testingpresentation

Reproduced using Xcode 16 Beta 2 / Swift 6

Checklist

Expected behavior

That the code compiles

Actual behavior

This code isn't compiling:

await store.send(\.destination.addContact.setName, "Blob Jr.") {
      $0.destination?.addContact?.contact.name = "Blob Jr."
}

Showing this error:

Setter for 'subscript(dynamicMember:)' is unavailable: Write 'enum = .case(value)', not 'enum.case = value'

Steps to reproduce

No response

The Composable Architecture version information

54eb417

Destination operating system

iOS 18

Xcode version information

Version 16.0 beta 2 (16A5171r)

Swift Compiler version information

swift-driver version: 1.110 Apple Swift version 6.0 (swiftlang-6.0.0.4.52 clang-1600.0.21.1.3)
Target: arm64-apple-macosx15.0
jshier commented 1 month ago

Yes, the subscript was always a bit of a hack, so they disabled in Swift 6 and now you should use .modify.

omarzl commented 1 month ago

Got it! I changed to:

await store.send(\.destination.addContact.setName, "Blob Jr.") {
  $0.destination?.modify(\.addContact) { $0.contact.name = "Blob Jr." }
}

And added support in the enum to CasePathable:

extension ContactsFeature {
  @CasePathable
  @Reducer(state: .equatable)
  enum Destination {
    case addContact(AddContactFeature)
    case alert(AlertState<ContactsFeature.Action.Alert>)
  }
}

Thanks!