Skip to content

Commit 8f0d39f

Browse files
committed
Sema: Stop finalizing struct and enum members
Since getStoredProperties() is a request that lowers lazy properties and property wrappers to their underlying storage, and SIL can validate stored property and enum element types, there's no longer any need for Sema to explicitly finalize members of structs and enums. SILGen can trigger any necessary type checkin work just by lowering a struct or enum type. Now the only remaining reason we need finalizeDecl() is adding implicit methods to classes, and synthesizing accessors for storage in classes and protocols.
1 parent 7388b46 commit 8f0d39f

File tree

4 files changed

+11
-46
lines changed

4 files changed

+11
-46
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2008,7 +2008,6 @@ void swift::triggerAccessorSynthesis(TypeChecker &TC,
20082008
if (!accessor->hasBody()) {
20092009
maybeMarkTransparent(accessor, TC.Context);
20102010
accessor->setBodySynthesizer(&synthesizeAccessorBody);
2011-
TC.DeclsToFinalize.insert(accessor);
20122011
}
20132012
});
20142013
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,7 +2319,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23192319
(void) VD->isDynamic();
23202320

23212321
// Make sure we finalize this declaration.
2322-
TC.DeclsToFinalize.insert(VD);
2322+
if (isa<ClassDecl>(VD) || isa<ProtocolDecl>(VD) ||
2323+
isa<AbstractStorageDecl>(VD))
2324+
TC.DeclsToFinalize.insert(VD);
23232325

23242326
// If this is a member of a nominal type, don't allow it to have a name of
23252327
// "Type" or "Protocol" since we reserve the X.Type and X.Protocol
@@ -3912,9 +3914,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
39123914
checkEnumRawValues(*this, ED);
39133915
}
39143916

3915-
if (!isa<ClassDecl>(nominal))
3916-
requestNominalLayout(nominal);
3917-
39183917
break;
39193918
}
39203919

@@ -4456,38 +4455,6 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
44564455
}
44574456
}
44584457

4459-
static bool shouldValidateMemberDuringFinalization(NominalTypeDecl *nominal,
4460-
ValueDecl *VD) {
4461-
// For enums, we only need to validate enum elements to know
4462-
// the layout.
4463-
if (isa<EnumDecl>(nominal) &&
4464-
isa<EnumElementDecl>(VD))
4465-
return true;
4466-
4467-
// For structs, we only need to validate stored properties to
4468-
// know the layout.
4469-
if (isa<StructDecl>(nominal) &&
4470-
(isa<VarDecl>(VD) &&
4471-
!cast<VarDecl>(VD)->isStatic() &&
4472-
(cast<VarDecl>(VD)->hasStorage() ||
4473-
VD->getAttrs().hasAttribute<LazyAttr>() ||
4474-
cast<VarDecl>(VD)->hasAttachedPropertyWrapper())))
4475-
return true;
4476-
4477-
// For classes, we need to validate properties and functions,
4478-
// but skipping nested types is OK.
4479-
if (isa<ClassDecl>(nominal) &&
4480-
!isa<TypeDecl>(VD))
4481-
return true;
4482-
4483-
// For protocols, skip nested typealiases and nominal types.
4484-
if (isa<ProtocolDecl>(nominal) &&
4485-
!isa<GenericTypeDecl>(VD))
4486-
return true;
4487-
4488-
return false;
4489-
}
4490-
44914458
void TypeChecker::requestMemberLayout(ValueDecl *member) {
44924459
auto *dc = member->getDeclContext();
44934460
if (auto *classDecl = dyn_cast<ClassDecl>(dc))
@@ -4530,13 +4497,11 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
45304497
// Force lowering of stored properties.
45314498
(void) nominal->getStoredProperties();
45324499

4533-
for (auto *D : nominal->getMembers()) {
4534-
auto VD = dyn_cast<ValueDecl>(D);
4535-
if (!VD)
4536-
continue;
4537-
4538-
if (shouldValidateMemberDuringFinalization(nominal, VD))
4539-
TC.DeclsToFinalize.insert(VD);
4500+
if (isa<ClassDecl>(nominal) || isa<ProtocolDecl>(nominal)) {
4501+
for (auto *D : nominal->getMembers()) {
4502+
if (auto *ASD = dyn_cast<AbstractStorageDecl>(D))
4503+
TC.DeclsToFinalize.insert(ASD);
4504+
}
45404505
}
45414506

45424507
if (auto *CD = dyn_cast<ClassDecl>(nominal)) {

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3703,7 +3703,8 @@ void ConformanceChecker::resolveValueWitnesses() {
37033703

37043704
// Make sure that we finalize the witness, so we can emit this
37053705
// witness table.
3706-
TC.DeclsToFinalize.insert(witness);
3706+
if (isa<AbstractStorageDecl>(witness))
3707+
TC.DeclsToFinalize.insert(witness);
37073708

37083709
// Objective-C checking for @objc requirements.
37093710
if (requirement->isObjC() &&
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
struct S {
2-
var a = S() // expected-error {{'S' cannot be constructed because it has no accessible initializers}}
2+
var a = S()
33
}

0 commit comments

Comments
 (0)