Hi. Is it possible in Swift 5.7 to use property wrapper with opaque result type?
@propertyWrapper ParamsStorage {
private var storage = Array< Param >()
var wrappedValue: some Collection<Param> { storage }
func addParam(_ param: Param) { storage.append(param) }
}
...
final class Event {
@ParamsStorage params: some Collection<Param>
// compiler error: Property type 'some Collection' (type of 'Event.params') does not match 'wrappedValue' type 'some Collection' (type of 'ParamsStorage.wrappedValue')
}
At the same time, the following code compiles:
final class Event {
private var _params: StatisticsParamsStorage = .init()
var params: some Collection<StatisticsEventParam> { _params.wrappedValue }
}
Seems like a bug in type inference. Is it expected behavior?
hborla
(Holly Borla)
2
Will you please file a bug at Issues · apple/swift · GitHub? In the meantime, you can work around the issue like this:
@propertyWrapper
struct ParamsStorage<Param> {
private var storage = Array<Param>()
var wrappedValue: some Collection<Param> { storage }
}
final class Event {
@ParamsStorage<Int> var params
}
The problem is that there's no way to express a some type of an existing declaration, so each appearance of some Collection<Param> is considered a different opaque type. However, the compiler can properly infer such a type, which is why dropping the type annotation works in this case (because property wrappers can infer the wrapped property type from var wrappedValue).