Property wrapper with Opaque Type

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?

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).

The bug is reported: Property wrapper with `Opaque Type` type inference · Issue #63056 · apple/swift · GitHub

1 Like