A little bit of context first. I wanted to write a property wrapper that could take a Combine Subject
and have the wrappedValue
expose an opaque type but still provide access to the Subject
for internal use. Example:
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct Test {
@MaskedSubject public var number = CurrentValueSubject<Int, Never>(0)
@MaskedSubject public var string = PassthroughSubject<String, Never>()
func publish() {
_number.send(_number.subject.value + 1)
_string.send("hello world!")
}
}
Here's my property wrapper
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper
public struct MaskedSubject<SubjectType: Subject> {
public typealias Output = SubjectType.Output
public typealias Failure = SubjectType.Failure
var subject: SubjectType
public init<S: Subject>(wrappedValue: S) where SubjectType == S {
subject = wrappedValue
}
public var wrappedValue: some Publisher<Output, Failure> { subject }
internal func send(_ value: Output) {
subject.send(value)
}
}
Notice the initializer looks like an error on my part. On the surface, that generic constraint is superfluous because it's got a same type requirement...but in actuality they're treated differently. Changing the initializer to:
public init(wrappedValue: SubjectType) {
subject = wrappedValue
}
Yields an error: error: 'init(wrappedValue:)' parameter type ('SubjectType') must be the same as its 'wrappedValue' property type ('some Publisher<SubjectType.Output, SubjectType.Failure>') or an @autoclosure thereof
So something seems like a bug. It's interesting to me that these are treated differently. I suspect that the bug is actually in the logic to check the property wrapper's initializer has the same type as the wrappedValue.