Several times I've run into a situation where I want to do something like the following:
@propertyWrapper
struct Wrapper {
var wrappedValue: Int
init() {
self.wrappedValue = 0
}
}
struct SomeType {
@Wrapper
var prop1: Int
var prop2: Int
init() {
self.prop2 = self.prop1
}
}
This, of course, fails on the self.prop2 = self.prop1
line with the following message:
'self' used before all stored properties are initialized
Because @Wrapper
makes prop1
a computed property, accessing it during init
constitutes an access to the entire self
value, which isn't permitted before all properties have been initialized.
However, the following (somewhat) analogous code compiles successfully:
struct SomeOtherType {
var prop1: Int = 0
var prop2: Int
init() {
self.prop2 = self.prop1
}
}
The compiler is smart enough to know that, while all of self
may not be initialized, at the very least self.prop1
is initialized and can be freely accessed.
The workaround for the wrapper case is to access wrappedValue
through the private storage:
self.prop2 = self._prop1.wrappedValue
Of course, this is by definition what the compiler has already synthesized for us in the computed prop1
getter. Forcing the user to write this breaks the property wrapper metaphor and leaks the underlying abstraction of synthesized getter/setter.
What do people think about allowing the line above (self.prop2 = self.prop1
) to compile, since the compiler knows that it is "just" a simple access to prop1
. Are there soundness holes that would actually in practice expose the uninitialized self
value (perhaps with property wrappers that use the "enclosing self
" feature)?
One potential downside here is that using a property wrapper would cease to be explainable in terms of simple sugar—the user would be able to write code with property wrappers that they couldn't also write "by hand" with a straightforward transformation. However, this is already the case via features like projectedValue
since the user is unable to define their own $
-identifier properties.
cc @hborla who I'm sure has strong opinions here