Skip to content

Commit 25570d9

Browse files
authored
Merge pull request #25588 from slavapestov/remove-parser-implicit-accessors
Stop synthesizing accessors inside the parser
2 parents 28dcc91 + c77784e commit 25570d9

File tree

10 files changed

+126
-146
lines changed

10 files changed

+126
-146
lines changed

lib/AST/Decl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,16 @@ bool AbstractStorageDecl::requiresOpaqueModifyCoroutine() const {
19071907
if (!supportsMutation())
19081908
return false;
19091909

1910+
auto *dc = getDeclContext();
1911+
1912+
// Local properties don't have modify accessors.
1913+
if (dc->isLocalContext())
1914+
return false;
1915+
1916+
// Fixed-layout global properties don't have modify accessors.
1917+
if (dc->isModuleScopeContext() && !isResilient())
1918+
return false;
1919+
19101920
// Imported storage declarations don't have eagerly-generated modify
19111921
// accessors.
19121922
if (hasClangNode())
@@ -1919,7 +1929,6 @@ bool AbstractStorageDecl::requiresOpaqueModifyCoroutine() const {
19191929
return false;
19201930

19211931
// Requirements of ObjC protocols don't support the modify coroutine.
1922-
auto *dc = getDeclContext();
19231932
if (auto protoDecl = dyn_cast<ProtocolDecl>(dc))
19241933
if (protoDecl->isObjC())
19251934
return false;

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4969,32 +4969,6 @@ Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
49694969
if (auto *subscript = dyn_cast<SubscriptDecl>(storage))
49704970
genericParams = subscript->getGenericParams();
49714971

4972-
// Create an implicit accessor declaration.
4973-
auto createImplicitAccessor = [&](AccessorKind kind,
4974-
AccessorDecl *funcForParams = nullptr) {
4975-
// We never use this to create addressors.
4976-
assert(kind != AccessorKind::Address &&
4977-
kind != AccessorKind::MutableAddress);
4978-
4979-
// Create the paramter list for a setter.
4980-
ParameterList *argList = nullptr;
4981-
if (kind == AccessorKind::Set) {
4982-
assert(funcForParams);
4983-
auto argLoc = funcForParams->getStartLoc();
4984-
4985-
auto argument = createSetterAccessorArgument(
4986-
argLoc, Identifier(), AccessorKind::Set, P, elementTy);
4987-
argList = ParameterList::create(P.Context, argument);
4988-
}
4989-
4990-
auto accessor = createAccessorFunc(SourceLoc(), argList,
4991-
genericParams, indices, elementTy,
4992-
staticLoc, flags, kind,
4993-
storage, &P, SourceLoc());
4994-
accessor->setImplicit();
4995-
add(accessor);
4996-
};
4997-
49984972
// If there was a problem parsing accessors, mark all parsed accessors
49994973
// as invalid to avoid tripping up later invariants.
50004974
// We also want to avoid diagnose missing accessors if something
@@ -5021,12 +4995,6 @@ Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
50214995

50224996
// Otherwise, we have either a stored or inherited observing property.
50234997
} else {
5024-
// Observing properties will have getters and setters synthesized
5025-
// by Sema. Create their prototypes now.
5026-
auto argFunc = (WillSet ? WillSet : DidSet);
5027-
createImplicitAccessor(AccessorKind::Get);
5028-
createImplicitAccessor(AccessorKind::Set, argFunc);
5029-
50304998
if (attrs.hasAttribute<OverrideAttr>()) {
50314999
return StorageImplInfo(ReadImplKind::Inherited,
50325000
WriteImplKind::InheritedWithObservers,
@@ -5067,7 +5035,7 @@ Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
50675035
isa<SubscriptDecl>(storage),
50685036
getAccessorNameForDiagnostic(mutator, /*article*/ true));
50695037
}
5070-
createImplicitAccessor(AccessorKind::Get);
5038+
50715039
readImpl = ReadImplKind::Get;
50725040

50735041
// Subscripts always have to have some sort of accessor; they can't be
@@ -5077,7 +5045,6 @@ Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
50775045
P.diagnose(LBLoc, diag::subscript_without_get);
50785046
}
50795047

5080-
createImplicitAccessor(AccessorKind::Get);
50815048
readImpl = ReadImplKind::Get;
50825049

50835050
// Otherwise, it's stored.

lib/SILGen/SILGen.cpp

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,48 +1316,17 @@ void SILGenModule::visitVarDecl(VarDecl *vd) {
13161316
if (vd->hasStorage())
13171317
addGlobalVariable(vd);
13181318

1319-
// Emit the variable's opaque accessors.
1320-
vd->visitExpectedOpaqueAccessors([&](AccessorKind kind) {
1321-
auto accessor = vd->getAccessor(kind);
1322-
if (!accessor) return;
1323-
1324-
// Only emit the accessor if it wasn't added to the surrounding decl
1325-
// list by the parser. We can test that easily by looking at the impl
1326-
// info, since all of these accessors have a corresponding access kind
1327-
// whose impl should definitely point at the accessor if it was parsed.
1328-
//
1329-
// This is an unfortunate formation rule, but it's easier than messing
1330-
// with the invariants for now.
1331-
bool shouldEmit = [&] {
1332-
auto impl = vd->getImplInfo();
1333-
switch (kind) {
1334-
case AccessorKind::Get:
1335-
return impl.getReadImpl() != ReadImplKind::Get &&
1336-
!(impl.getReadImpl() == ReadImplKind::Stored &&
1337-
impl.getWriteImpl() == WriteImplKind::StoredWithObservers);
1338-
case AccessorKind::Read:
1339-
return impl.getReadImpl() != ReadImplKind::Read;
1340-
case AccessorKind::Set:
1341-
return impl.getWriteImpl() != WriteImplKind::Set &&
1342-
impl.getWriteImpl() != WriteImplKind::StoredWithObservers;
1343-
case AccessorKind::Modify:
1344-
return impl.getReadWriteImpl() != ReadWriteImplKind::Modify;
1345-
#define ACCESSOR(ID) \
1346-
case AccessorKind::ID:
1347-
#define OPAQUE_ACCESSOR(ID, KEYWORD)
1348-
#include "swift/AST/AccessorKinds.def"
1349-
llvm_unreachable("not an opaque accessor");
1350-
}
1351-
llvm_unreachable("covered switch");
1352-
}();
1353-
if (!shouldEmit) return;
1354-
1319+
for (auto *accessor : vd->getAllAccessors())
13551320
emitFunction(accessor);
1356-
});
13571321

13581322
tryEmitPropertyDescriptor(vd);
13591323
}
13601324

1325+
void SILGenModule::visitSubscriptDecl(SubscriptDecl *sd) {
1326+
for (auto *accessor : sd->getAllAccessors())
1327+
emitFunction(accessor);
1328+
}
1329+
13611330
bool
13621331
SILGenModule::canStorageUseStoredKeyPathComponent(AbstractStorageDecl *decl,
13631332
ResilienceExpansion expansion) {

lib/SILGen/SILGen.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,14 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
188188
void visitTypeAliasDecl(TypeAliasDecl *d) {}
189189
void visitOpaqueTypeDecl(OpaqueTypeDecl *d) {}
190190
void visitAbstractTypeParamDecl(AbstractTypeParamDecl *d) {}
191-
void visitSubscriptDecl(SubscriptDecl *d) {}
192191
void visitConstructorDecl(ConstructorDecl *d) {}
193192
void visitDestructorDecl(DestructorDecl *d) {}
194193
void visitModuleDecl(ModuleDecl *d) { }
195194
void visitMissingMemberDecl(MissingMemberDecl *d) {}
196195

196+
// Emitted as part of its storage.
197+
void visitAccessorDecl(AccessorDecl *ad) {}
198+
197199
void visitFuncDecl(FuncDecl *fd);
198200
void visitPatternBindingDecl(PatternBindingDecl *vd);
199201
void visitTopLevelCodeDecl(TopLevelCodeDecl *td);
@@ -202,6 +204,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
202204
void visitNominalTypeDecl(NominalTypeDecl *ntd);
203205
void visitExtensionDecl(ExtensionDecl *ed);
204206
void visitVarDecl(VarDecl *vd);
207+
void visitSubscriptDecl(SubscriptDecl *sd);
205208

206209
void emitAbstractFuncDecl(AbstractFunctionDecl *AFD);
207210

lib/SILGen/SILGenDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,10 @@ void SILGenFunction::visitPatternBindingDecl(PatternBindingDecl *PBD) {
11921192

11931193
void SILGenFunction::visitVarDecl(VarDecl *D) {
11941194
// We handle emitting the variable storage when we see the pattern binding.
1195+
1196+
// Emit the variable's accessors.
1197+
for (auto *accessor : D->getAllAccessors())
1198+
SGM.emitFunction(accessor);
11951199
}
11961200

11971201
/// Emit literals for the major, minor, and subminor components of the version

lib/SILGen/SILGenFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
17871787
llvm_unreachable("Not yet implemented");
17881788
}
17891789

1790+
// Emitted as part of its storage.
1791+
void visitAccessorDecl(AccessorDecl *D) {}
1792+
17901793
void visitFuncDecl(FuncDecl *D);
17911794
void visitPatternBindingDecl(PatternBindingDecl *D);
17921795

lib/Sema/CodeSynthesis.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static void addMemberToContextIfNeeded(Decl *D, DeclContext *DC,
7272
} else if (auto *ed = dyn_cast<ExtensionDecl>(DC)) {
7373
ed->addMember(D, Hint);
7474
} else {
75-
assert((isa<AbstractFunctionDecl>(DC) || isa<FileUnit>(DC)) &&
75+
assert((DC->isLocalContext() || isa<FileUnit>(DC)) &&
7676
"Unknown declcontext");
7777
}
7878
}
@@ -2036,8 +2036,8 @@ void swift::maybeAddAccessorsToStorage(AbstractStorageDecl *storage) {
20362036

20372037
auto *dc = storage->getDeclContext();
20382038

2039-
// Local variables don't otherwise get accessors.
2040-
if (dc->isLocalContext())
2039+
// Local stored variables don't otherwise get accessors.
2040+
if (dc->isLocalContext() && storage->getImplInfo().isSimpleStored())
20412041
return;
20422042

20432043
// Implicit properties don't get accessors.
@@ -2053,7 +2053,7 @@ void swift::maybeAddAccessorsToStorage(AbstractStorageDecl *storage) {
20532053
return;
20542054
}
20552055
// Fixed-layout global variables don't get accessors.
2056-
if (!storage->isResilient())
2056+
if (!storage->isResilient() && storage->getImplInfo().isSimpleStored())
20572057
return;
20582058

20592059
// In a protocol context, variables written as just "var x : Int" or

0 commit comments

Comments
 (0)