@@ -1669,7 +1669,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
16691669 case WriteImplKind::Modify:
16701670 return synthesizeModifyCoroutineSetterBody (setter, ctx);
16711671 }
1672- llvm_unreachable (" bad ReadImplKind " );
1672+ llvm_unreachable (" bad WriteImplKind " );
16731673}
16741674
16751675static std::pair<BraceStmt *, bool >
@@ -1950,7 +1950,75 @@ static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
19501950
19511951 // All mutable storage requires a setter.
19521952 assert (storage->requiresOpaqueAccessor (AccessorKind::Set));
1953+
1954+ // Copy availability from the accessor we'll synthesize the setter from.
1955+ SmallVector<Decl *, 2 > asAvailableAs;
1956+
1957+ // That could be a property wrapper...
1958+ if (auto var = dyn_cast<VarDecl>(storage)) {
1959+ if (var->hasAttachedPropertyWrapper ()) {
1960+ // The property wrapper info may not actually link back to a wrapper
1961+ // implementation, if there was a semantic error checking the wrapper.
1962+ auto info = var->getAttachedPropertyWrapperTypeInfo (0 );
1963+ if (info.valueVar ) {
1964+ if (auto setter = info.valueVar ->getOpaqueAccessor (AccessorKind::Set)) {
1965+ asAvailableAs.push_back (setter);
1966+ }
1967+ }
1968+ } else if (auto wrapperSynthesizedKind
1969+ = var->getPropertyWrapperSynthesizedPropertyKind ()) {
1970+ switch (*wrapperSynthesizedKind) {
1971+ case PropertyWrapperSynthesizedPropertyKind::Backing:
1972+ break ;
1973+
1974+ case PropertyWrapperSynthesizedPropertyKind::StorageWrapper: {
1975+ if (auto origVar = var->getOriginalWrappedProperty (wrapperSynthesizedKind)) {
1976+ // The property wrapper info may not actually link back to a wrapper
1977+ // implementation, if there was a semantic error checking the wrapper.
1978+ auto info = origVar->getAttachedPropertyWrapperTypeInfo (0 );
1979+ if (info.projectedValueVar ) {
1980+ if (auto setter
1981+ = info.projectedValueVar ->getOpaqueAccessor (AccessorKind::Set)){
1982+ asAvailableAs.push_back (setter);
1983+ }
1984+ }
1985+ }
1986+ break ;
1987+ }
1988+ }
1989+ }
1990+ }
19531991
1992+
1993+ // ...or another accessor.
1994+ switch (storage->getWriteImpl ()) {
1995+ case WriteImplKind::Immutable:
1996+ llvm_unreachable (" synthesizing setter from immutable storage" );
1997+ case WriteImplKind::Stored:
1998+ case WriteImplKind::StoredWithObservers:
1999+ case WriteImplKind::InheritedWithObservers:
2000+ case WriteImplKind::Set:
2001+ // Setter's availability shouldn't be externally influenced in these
2002+ // cases.
2003+ break ;
2004+
2005+ case WriteImplKind::MutableAddress:
2006+ if (auto addr = storage->getOpaqueAccessor (AccessorKind::MutableAddress)) {
2007+ asAvailableAs.push_back (addr);
2008+ }
2009+ break ;
2010+ case WriteImplKind::Modify:
2011+ if (auto mod = storage->getOpaqueAccessor (AccessorKind::Modify)) {
2012+ asAvailableAs.push_back (mod);
2013+ }
2014+ break ;
2015+ }
2016+
2017+ if (!asAvailableAs.empty ()) {
2018+ AvailabilityInference::applyInferredAvailableAttrs (
2019+ setter, asAvailableAs, ctx);
2020+ }
2021+
19542022 finishImplicitAccessor (setter, ctx);
19552023
19562024 return setter;
0 commit comments