This is why I specifically said how it's used as a property wrapper, not as a regular type. Yes, you can extend types you don't own in Swift to add functionality, but this same principle doesn't apply the same way to property wrappers. For example, you can't extend the wrapper to add your own wrappedValue
setter if the wrapper doesn't provide one. You also can't extend a wrapper and add your own projectedValue
to opt into $
syntax when applying the wrapper to a property.
Property wrappers also already have special initializer lookup rules to determine whether a property wrapper can be initialized out of line or default initialized - lookup is done directly on the nominal type (it doesn't even look in extensions within the defining module, let alone outside of it). If it can be initialized using one of these special mechanisms, then the initializer expression is built and type checked normally, which is why I was considering two levels of type checking. The only exception is when you initialize the property wrapper inline using =
. Then, the type-checked initializer expression is used to determine which type the memberwise initializer takes in, and whether the backing wrapper can be (re)-initialized out-of-line via wrapped value. I'm not sure if this was a deliberate design decision or an oversight, because it's certainly inconsistent.
Deciding whether a wrapper is part of a (potentially public) function signature, affects ABI, etc, is a very different and much more impactful decision, and it's not sound for this decision to be made differently across modules for the same property wrapper attribute.
No, it's not (I already answered this question in a different thread, and I will add this clarification to the proposal). The whole idea behind "API wrapper" is that a wrapper is only API if it needs to impact the argument at the call-site. This wrapper does not, unless its init(wrappedValue:)
needs an @autoclosure
.