@@ -1669,7 +1669,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
1669
1669
case WriteImplKind::Modify:
1670
1670
return synthesizeModifyCoroutineSetterBody (setter, ctx);
1671
1671
}
1672
- llvm_unreachable (" bad ReadImplKind " );
1672
+ llvm_unreachable (" bad WriteImplKind " );
1673
1673
}
1674
1674
1675
1675
static std::pair<BraceStmt *, bool >
@@ -1950,7 +1950,75 @@ static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
1950
1950
1951
1951
// All mutable storage requires a setter.
1952
1952
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
+ }
1953
1991
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
+
1954
2022
finishImplicitAccessor (setter, ctx);
1955
2023
1956
2024
return setter;
0 commit comments