[SR-11280] PropertyWrapper property + didSet Property Observer results in get before set failure #53681
Labels
bug
A deviation from expected or documented behavior. Also: expected but undesirable behavior.
compiler
The Swift compiler in itself
property wrappers
Feature: property wrappers
SILGen
Area → compiler: The SIL generation stage
Attachment: Download
Environment
Xcode Version 11.0 beta 5 (11M382q)
Please try this out in the attached playground.
See also FB6975769
Additional Detail from JIRA
md5: 7039dab2460e6310b9ed7f65d3540b71
is duplicated by:
Issue Description:
Using a property wrapper equivalent to the LateInitialized example from WWDC 2019 in combination with a `didSet` side effect on the same property causes the wrappedValue getter to be called as part of setting the value.
I believe the combination of PropertyWrapper and didSet Property Observer are incompatible in this case because the initialization of the storage has not occurred when the oldValue getter occurred. The diagnostics around this issue are incomplete.
See attached playground for example. Changing the didSet to a willSet avoids the get-before-set error but is not a desirable workaround.
Succinctly
Attempting to set state.value in this way causes the @DeferredInitialization wrappedValue getter to be before the actual value is set. Presumably this occurs because the didSet is capturing the oldValue from uninitialized storage.
This may be an intractable problem because these two features should not be combined in this manner, however at a minimum a diagnostic should appear or the use of oldValue in the didSet should be the trigger for this issue.
I did not expect didSet to have the side effect of calling a getter whose PropertyWrapper backing storage has not been initialized.
Ideally a LateInitialized/DeferredInitialization property wrapper should be part of the standard library and include an appropriate workaround such that a didSet Property Observer can be used in combination with the property wrapper as long as the oldValue is not accessed.
In some ways the “magic” of oldValue is surprising. It seems exceptional in swift that
is possible as the provenance of oldValue is “magic”.
Its almost as though didSet should work more like
where
And
Would not trigger the oldValue getter and thus be more compatible with a propertyWrapper of this style.
Understandably this would be a significant, code-breaking change to the syntax of the didSet property observer.
The text was updated successfully, but these errors were encountered: