Skip to content

Commit 0a5de7a

Browse files
committed
[Property Wrappers] Implement availability inference for the _modify accessor
of a wrapped property.
1 parent 1efb638 commit 0a5de7a

File tree

1 file changed

+44
-35
lines changed

1 file changed

+44
-35
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,45 @@ static AccessorDecl *createGetterPrototype(AbstractStorageDecl *storage,
19261926
return getter;
19271927
}
19281928

1929+
static void addPropertyWrapperAccessorAvailability(VarDecl *var, AccessorKind accessorKind,
1930+
SmallVectorImpl<const Decl *> &asAvailableAs) {
1931+
AccessorDecl *synthesizedFrom = nullptr;
1932+
if (var->hasAttachedPropertyWrapper()) {
1933+
// The property wrapper info may not actually link back to a wrapper
1934+
// implementation, if there was a semantic error checking the wrapper.
1935+
auto info = var->getAttachedPropertyWrapperTypeInfo(0);
1936+
if (info.valueVar) {
1937+
synthesizedFrom = info.valueVar->getOpaqueAccessor(accessorKind);
1938+
}
1939+
} else if (auto wrapperSynthesizedKind
1940+
= var->getPropertyWrapperSynthesizedPropertyKind()) {
1941+
switch (*wrapperSynthesizedKind) {
1942+
case PropertyWrapperSynthesizedPropertyKind::Backing:
1943+
break;
1944+
1945+
case PropertyWrapperSynthesizedPropertyKind::Projection: {
1946+
if (auto origVar = var->getOriginalWrappedProperty(wrapperSynthesizedKind)) {
1947+
// The property wrapper info may not actually link back to a wrapper
1948+
// implementation, if there was a semantic error checking the wrapper.
1949+
auto info = origVar->getAttachedPropertyWrapperTypeInfo(0);
1950+
if (info.projectedValueVar) {
1951+
synthesizedFrom = info.projectedValueVar->getOpaqueAccessor(accessorKind);
1952+
}
1953+
}
1954+
break;
1955+
}
1956+
}
1957+
}
1958+
1959+
// Infer availability from the accessor used for synthesis, and intersect it
1960+
// with the availability of the enclosing scope.
1961+
if (synthesizedFrom) {
1962+
asAvailableAs.push_back(synthesizedFrom);
1963+
if (auto *enclosingDecl = var->getInnermostDeclWithAvailability())
1964+
asAvailableAs.push_back(enclosingDecl);
1965+
}
1966+
}
1967+
19291968
static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
19301969
ASTContext &ctx,
19311970
AccessorDecl *getter = nullptr) {
@@ -1971,41 +2010,7 @@ static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
19712010

19722011
// That could be a property wrapper...
19732012
if (auto var = dyn_cast<VarDecl>(storage)) {
1974-
if (var->hasAttachedPropertyWrapper()) {
1975-
// The property wrapper info may not actually link back to a wrapper
1976-
// implementation, if there was a semantic error checking the wrapper.
1977-
auto info = var->getAttachedPropertyWrapperTypeInfo(0);
1978-
if (info.valueVar) {
1979-
if (auto setter = info.valueVar->getOpaqueAccessor(AccessorKind::Set)) {
1980-
asAvailableAs.push_back(setter);
1981-
if (auto *enclosing = var->getInnermostDeclWithAvailability())
1982-
asAvailableAs.push_back(enclosing);
1983-
}
1984-
}
1985-
} else if (auto wrapperSynthesizedKind
1986-
= var->getPropertyWrapperSynthesizedPropertyKind()) {
1987-
switch (*wrapperSynthesizedKind) {
1988-
case PropertyWrapperSynthesizedPropertyKind::Backing:
1989-
break;
1990-
1991-
case PropertyWrapperSynthesizedPropertyKind::Projection: {
1992-
if (auto origVar = var->getOriginalWrappedProperty(wrapperSynthesizedKind)) {
1993-
// The property wrapper info may not actually link back to a wrapper
1994-
// implementation, if there was a semantic error checking the wrapper.
1995-
auto info = origVar->getAttachedPropertyWrapperTypeInfo(0);
1996-
if (info.projectedValueVar) {
1997-
if (auto setter
1998-
= info.projectedValueVar->getOpaqueAccessor(AccessorKind::Set)){
1999-
asAvailableAs.push_back(setter);
2000-
if (auto *enclosing = var->getInnermostDeclWithAvailability())
2001-
asAvailableAs.push_back(enclosing);
2002-
}
2003-
}
2004-
}
2005-
break;
2006-
}
2007-
}
2008-
}
2013+
addPropertyWrapperAccessorAvailability(var, AccessorKind::Set, asAvailableAs);
20092014
}
20102015

20112016

@@ -2099,6 +2104,10 @@ createCoroutineAccessorPrototype(AbstractStorageDecl *storage,
20992104
}
21002105
}
21012106

2107+
if (auto var = dyn_cast<VarDecl>(storage)) {
2108+
addPropertyWrapperAccessorAvailability(var, kind, asAvailableAs);
2109+
}
2110+
21022111
AvailabilityInference::applyInferredAvailableAttrs(accessor,
21032112
asAvailableAs, ctx);
21042113

0 commit comments

Comments
 (0)