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