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.61k stars 1.46k forks source link

Custom propertyWrapper in State: Compiler error when using new @ObservableState macro #2859

Closed mschonvogel closed 9 months ago

mschonvogel commented 9 months ago

Description

When using a propertyWrapper in the state in combination with the @ObservableState macro, it causes a compiler error:

Property wrapper cannot be applied to a computed property.

Here's a reproducible project: TCAState PropertyWrapper.zip

Here's an example propertyWrapper :

@propertyWrapper
public struct Placeholder<Value: Equatable & Redactable>: Equatable {
    public var wrappedValue: Value {
        get {
            projectedValue.value
        } set {
            projectedValue.value = newValue
        }
    }

    public var projectedValue: Projected

    public init(wrappedValue: Value = .placeholder) {
        self.projectedValue = Projected(value: wrappedValue)
    }

    public struct Projected: Equatable {
        var value: Value

        public var isLoading: Bool {
            value == Value.placeholder
        }
    }
}

public protocol Redactable {
    static var placeholder: Self { get }
}

public protocol RedactableArray {
    static var placeholders: [Self] { get }
}

extension Array: Redactable where Element: RedactableArray {
    public static var placeholder: [Element] {
        Element.placeholders
    }
}

State:

@Reducer
struct ContentViewFeature {
    @ObservableState
    struct State {
        @Placeholder var users: [User]

        var isRedacted: Bool {
            $users.isLoading
        }
    }

    enum Action {}

    var body: some ReducerOf<Self> {
        Reduce { state, action in
            .none
        }
    }
}

Checklist

Expected behavior

The project should compile successfully (as prior to updating to the @ObservableState macro)

Actual behavior

Error while compiling

Property wrapper cannot be applied to a computed property.

Steps to reproduce

No response

The Composable Architecture version information

1.8.2

Destination operating system

iOS 17

Xcode version information

15.2

Swift Compiler version information

swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: arm64-apple-macosx14.0
mbrandonw commented 9 months ago

Hi @mschonvogel, this is just a problem with Swift macros in general. It won't work with Swift's @Observable macro or SwiftUI's @Model macro either:

@Observable 
class Foo { var count = 0 }  // 🛑
@Model 
class Bar { var count = 0 }  // 🛑

Since this is not an issue with the library I am going to convert it to a discussion.