@@ -757,6 +757,8 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
757
757
bool isMemberLValue = isLValue;
758
758
auto propertyWrapperMutability =
759
759
[&](Decl *decl) -> Optional<std::pair<bool , bool >> {
760
+ if (target != TargetImpl::Wrapper && target != TargetImpl::WrapperStorage)
761
+ return None;
760
762
auto var = dyn_cast<VarDecl>(decl);
761
763
if (!var)
762
764
return None;
@@ -1531,8 +1533,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
1531
1533
}
1532
1534
1533
1535
if (var->hasAttachedPropertyWrapper ()) {
1534
- if (var->getParsedAccessor (AccessorKind::WillSet) ||
1535
- var->getParsedAccessor (AccessorKind::DidSet)) {
1536
+ if (var->hasObservers ()) {
1536
1537
return synthesizeObservedSetterBody (setter, TargetImpl::Wrapper, ctx);
1537
1538
}
1538
1539
@@ -1580,20 +1581,24 @@ synthesizeCoroutineAccessorBody(AccessorDecl *accessor, ASTContext &ctx) {
1580
1581
assert (accessor->isCoroutine ());
1581
1582
1582
1583
auto storage = accessor->getStorage ();
1584
+ auto storageReadWriteImpl = storage->getReadWriteImpl ();
1583
1585
auto target = (accessor->hasForcedStaticDispatch ()
1584
1586
? TargetImpl::Ordinary
1585
1587
: TargetImpl::Implementation);
1586
1588
1587
1589
// If this is a variable with an attached property wrapper, then
1588
1590
// the accessors need to yield the wrappedValue or projectedValue.
1589
- if (auto var = dyn_cast<VarDecl>(storage)) {
1590
- if (var->hasAttachedPropertyWrapper ()) {
1591
- target = TargetImpl::Wrapper;
1592
- }
1591
+ if (accessor->getAccessorKind () == AccessorKind::Read ||
1592
+ storageReadWriteImpl == ReadWriteImplKind::Modify) {
1593
+ if (auto var = dyn_cast<VarDecl>(storage)) {
1594
+ if (var->hasAttachedPropertyWrapper ()) {
1595
+ target = TargetImpl::Wrapper;
1596
+ }
1593
1597
1594
- if (var->getOriginalWrappedProperty (
1595
- PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
1596
- target = TargetImpl::WrapperStorage;
1598
+ if (var->getOriginalWrappedProperty (
1599
+ PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
1600
+ target = TargetImpl::WrapperStorage;
1601
+ }
1597
1602
}
1598
1603
}
1599
1604
@@ -2043,8 +2048,7 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
2043
2048
// FIXME: This should be folded into the WriteImplKind below.
2044
2049
if (auto var = dyn_cast<VarDecl>(storage)) {
2045
2050
if (var->hasAttachedPropertyWrapper ()) {
2046
- if (var->getParsedAccessor (AccessorKind::DidSet) ||
2047
- var->getParsedAccessor (AccessorKind::WillSet))
2051
+ if (var->hasObservers ())
2048
2052
return false ;
2049
2053
2050
2054
break ;
@@ -2581,11 +2585,17 @@ static void finishPropertyWrapperImplInfo(VarDecl *var,
2581
2585
}
2582
2586
}
2583
2587
2584
- if (wrapperSetterIsUsable)
2588
+ if (!wrapperSetterIsUsable) {
2589
+ info = StorageImplInfo::getImmutableComputed ();
2590
+ return ;
2591
+ }
2592
+
2593
+ if (var->hasObservers ()) {
2594
+ info = StorageImplInfo::getMutableComputed ();
2595
+ } else {
2585
2596
info = StorageImplInfo (ReadImplKind::Get, WriteImplKind::Set,
2586
2597
ReadWriteImplKind::Modify);
2587
- else
2588
- info = StorageImplInfo::getImmutableComputed ();
2598
+ }
2589
2599
}
2590
2600
2591
2601
static void finishNSManagedImplInfo (VarDecl *var,
0 commit comments