Skip to content

Commit ec465e1

Browse files
authored
Merge pull request #31212 from slavapestov/direct-to-storage-cleanup
Sema: Merge shouldAccessStorageDirectly() into isDirectToStorageAccess()
2 parents 03f4b34 + 96b0678 commit ec465e1

File tree

2 files changed

+41
-75
lines changed

2 files changed

+41
-75
lines changed

lib/AST/Decl.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,45 +1972,63 @@ static bool isPolymorphic(const AbstractStorageDecl *storage) {
19721972
return false;
19731973
}
19741974

1975-
static bool isDirectToStorageAccess(const AccessorDecl *accessor,
1975+
static bool isDirectToStorageAccess(const DeclContext *UseDC,
19761976
const VarDecl *var, bool isAccessOnSelf) {
1977-
// All accesses have ordinary semantics except those to variables
1978-
// with storage from within their own accessors.
1979-
if (accessor->getStorage() != var)
1977+
if (!var->hasStorage())
19801978
return false;
19811979

1982-
if (!var->hasStorage())
1980+
auto *AFD = dyn_cast<AbstractFunctionDecl>(UseDC);
1981+
if (AFD == nullptr)
19831982
return false;
19841983

1985-
// In Swift 5 and later, the access must also be a member access on 'self'.
1986-
if (!isAccessOnSelf &&
1987-
var->getDeclContext()->isTypeContext() &&
1988-
var->getASTContext().isSwiftVersionAtLeast(5))
1984+
// The property reference is for immediate class, not a derived class.
1985+
if (AFD->getParent()->getSelfNominalTypeDecl() !=
1986+
var->getDeclContext()->getSelfNominalTypeDecl())
19891987
return false;
19901988

1991-
// As a special case, 'read' and 'modify' coroutines with forced static
1992-
// dispatch must use ordinary semantics, so that the 'modify' coroutine for a
1993-
// 'dynamic' property uses Objective-C message sends and not direct access to
1994-
// storage.
1995-
if (accessor->hasForcedStaticDispatch())
1989+
// If the storage is resilient, we cannot access it directly at all.
1990+
if (var->isResilient(UseDC->getParentModule(),
1991+
UseDC->getResilienceExpansion()))
19961992
return false;
19971993

1998-
return true;
1994+
if (isa<ConstructorDecl>(AFD) || isa<DestructorDecl>(AFD)) {
1995+
// The access must also be a member access on 'self' in all language modes.
1996+
if (!isAccessOnSelf)
1997+
return false;
1998+
1999+
return true;
2000+
} else if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
2001+
// The accessor must be for the variable itself.
2002+
if (accessor->getStorage() != var)
2003+
return false;
2004+
2005+
// In Swift 5 and later, the access must also be a member access on 'self'.
2006+
if (!isAccessOnSelf &&
2007+
var->getDeclContext()->isTypeContext() &&
2008+
var->getASTContext().isSwiftVersionAtLeast(5))
2009+
return false;
2010+
2011+
// As a special case, 'read' and 'modify' coroutines with forced static
2012+
// dispatch must use ordinary semantics, so that the 'modify' coroutine for a
2013+
// 'dynamic' property uses Objective-C message sends and not direct access to
2014+
// storage.
2015+
if (accessor->hasForcedStaticDispatch())
2016+
return false;
2017+
2018+
return true;
2019+
}
2020+
2021+
return false;
19992022
}
20002023

20012024
/// Determines the access semantics to use in a DeclRefExpr or
20022025
/// MemberRefExpr use of this value in the specified context.
20032026
AccessSemantics
20042027
ValueDecl::getAccessSemanticsFromContext(const DeclContext *UseDC,
20052028
bool isAccessOnSelf) const {
2006-
// The condition most likely to fast-path us is not being in an accessor,
2007-
// so we check that first.
2008-
if (auto *accessor = dyn_cast<AccessorDecl>(UseDC)) {
2009-
if (auto *var = dyn_cast<VarDecl>(this)) {
2010-
if (isDirectToStorageAccess(accessor, var, isAccessOnSelf))
2011-
return AccessSemantics::DirectToStorage;
2012-
}
2013-
}
2029+
if (auto *var = dyn_cast<VarDecl>(this))
2030+
if (isDirectToStorageAccess(UseDC, var, isAccessOnSelf))
2031+
return AccessSemantics::DirectToStorage;
20142032

20152033
// Otherwise, it's a semantically normal access. The client should be
20162034
// able to figure out the most efficient way to do this access.

lib/Sema/CSApply.cpp

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -110,49 +110,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
110110
return ConcreteDeclRef(decl, computeSubstitutions(sig, locator));
111111
}
112112

113-
static bool shouldAccessStorageDirectly(Expr *base, VarDecl *member,
114-
DeclContext *DC) {
115-
// This only matters for stored properties.
116-
if (!member->hasStorage())
117-
return false;
118-
119-
// ... referenced from constructors and destructors.
120-
auto *AFD = dyn_cast<AbstractFunctionDecl>(DC);
121-
if (AFD == nullptr)
122-
return false;
123-
124-
if (!isa<ConstructorDecl>(AFD) && !isa<DestructorDecl>(AFD))
125-
return false;
126-
127-
// ... via a "self.property" reference.
128-
auto *DRE = dyn_cast<DeclRefExpr>(base);
129-
if (DRE == nullptr)
130-
return false;
131-
132-
if (AFD->getImplicitSelfDecl() != cast<DeclRefExpr>(base)->getDecl())
133-
return false;
134-
135-
// Convenience initializers do not require special handling.
136-
// FIXME: This is a language change -- for now, keep the old behavior
137-
#if 0
138-
if (auto *CD = dyn_cast<ConstructorDecl>(AFD))
139-
if (!CD->isDesignatedInit())
140-
return false;
141-
#endif
142-
143-
// Ctor or dtor are for immediate class, not a derived class.
144-
if (!AFD->getParent()->getDeclaredInterfaceType()->isEqual(
145-
member->getDeclContext()->getDeclaredInterfaceType()))
146-
return false;
147-
148-
// If the storage is resilient, we cannot access it directly at all.
149-
if (member->isResilient(DC->getParentModule(),
150-
DC->getResilienceExpansion()))
151-
return false;
152-
153-
return true;
154-
}
155-
156113
ConstraintLocator *Solution::getCalleeLocator(ConstraintLocator *locator,
157114
bool lookThroughApply) const {
158115
auto &cs = getConstraintSystem();
@@ -184,15 +141,6 @@ Solution::getConstraintLocator(ConstraintLocator *base,
184141
static AccessSemantics
185142
getImplicitMemberReferenceAccessSemantics(Expr *base, VarDecl *member,
186143
DeclContext *DC) {
187-
// Properties that have storage and accessors are frequently accessed through
188-
// accessors. However, in the init and destructor methods for the type
189-
// immediately containing the property, accesses are done direct.
190-
if (shouldAccessStorageDirectly(base, member, DC)) {
191-
// Access this directly instead of going through (e.g.) observing or
192-
// trivial accessors.
193-
return AccessSemantics::DirectToStorage;
194-
}
195-
196144
// Check whether this is a member access on 'self'.
197145
bool isAccessOnSelf = false;
198146
if (auto *baseDRE = dyn_cast<DeclRefExpr>(base->getValueProvidingExpr()))

0 commit comments

Comments
 (0)