Skip to content

Commit 95c221a

Browse files
committed
Sema: Replace makeFinal() calls in favor of smarter IsFinalRequest
1 parent 4a8e3fc commit 95c221a

File tree

3 files changed

+18
-27
lines changed

3 files changed

+18
-27
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,10 +1628,6 @@ void swift::completeLazyVarImplementation(VarDecl *VD) {
16281628
Storage->setLazyStorageProperty(true);
16291629
Storage->setUserAccessible(false);
16301630

1631-
// Mark the backing property as 'final'. There's no sensible way to override.
1632-
if (VD->getDeclContext()->getSelfClassDecl())
1633-
makeFinal(Context, Storage);
1634-
16351631
addMemberToContextIfNeeded(Storage, VD->getDeclContext(), VD);
16361632

16371633
// Create the pattern binding decl for the storage decl. This will get
@@ -1798,10 +1794,6 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
17981794
backingVar->setInvalid();
17991795
backingVar->setOriginalWrappedProperty(var);
18001796

1801-
// Mark the backing property as 'final'. There's no sensible way to override.
1802-
if (dc->getSelfClassDecl())
1803-
makeFinal(ctx, backingVar);
1804-
18051797
// The backing storage is 'private'.
18061798
backingVar->overwriteAccess(AccessLevel::Private);
18071799
backingVar->overwriteSetterAccess(AccessLevel::Private);

lib/Sema/CodeSynthesis.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ class TypeChecker;
4242

4343
class ObjCReason;
4444

45-
// These are implemented in TypeCheckDecl.cpp.
46-
void makeFinal(ASTContext &ctx, ValueDecl *D);
47-
4845
// Implemented in TypeCheckerOverride.cpp
4946
bool checkOverrides(ValueDecl *decl);
5047

lib/Sema/TypeCheckDecl.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,11 +1050,6 @@ static void validatePatternBindingEntries(TypeChecker &tc,
10501050
validatePatternBindingEntry(tc, binding, i);
10511051
}
10521052

1053-
void swift::makeFinal(ASTContext &ctx, ValueDecl *D) {
1054-
assert(isa<ClassDecl>(D) || D->isPotentiallyOverridable());
1055-
D->getAttrs().add(new (ctx) FinalAttr(/*IsImplicit=*/true));
1056-
}
1057-
10581053
namespace {
10591054
// The raw values of this enum must be kept in sync with
10601055
// diag::implicitly_final_cannot_be_open.
@@ -1068,12 +1063,8 @@ enum class ImplicitlyFinalReason : unsigned {
10681063
};
10691064
}
10701065

1071-
static bool inferFinalAndDiagnoseIfNeeded(ValueDecl *D,
1066+
static bool inferFinalAndDiagnoseIfNeeded(ValueDecl *D, ClassDecl *cls,
10721067
StaticSpellingKind staticSpelling) {
1073-
auto cls = D->getDeclContext()->getSelfClassDecl();
1074-
if (!cls)
1075-
return false;
1076-
10771068
// Are there any reasons to infer 'final'? Prefer 'static' over the class
10781069
// being final for the purposes of diagnostics.
10791070
Optional<ImplicitlyFinalReason> reason;
@@ -1184,15 +1175,28 @@ doesAccessorNeedDynamicAttribute(AccessorDecl *accessor, Evaluator &evaluator) {
11841175

11851176
llvm::Expected<bool>
11861177
IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
1178+
if (isa<ClassDecl>(decl))
1179+
return decl->getAttrs().hasAttribute<FinalAttr>();
1180+
1181+
auto cls = decl->getDeclContext()->getSelfClassDecl();
1182+
if (!cls)
1183+
return false;
1184+
11871185
switch (decl->getKind()) {
11881186
case DeclKind::Var: {
11891187
// Properties are final if they are declared 'static' or a 'let'
11901188
auto *VD = cast<VarDecl>(decl);
1189+
1190+
// Backing storage for 'lazy' or property wrappers is always final.
1191+
if (VD->isLazyStorageProperty() ||
1192+
VD->getOriginalWrappedProperty())
1193+
return true;
1194+
11911195
if (auto *nominalDecl = VD->getDeclContext()->getSelfClassDecl()) {
11921196
// If this variable is a class member, mark it final if the
11931197
// class is final, or if it was declared with 'let'.
11941198
auto *PBD = VD->getParentPatternBinding();
1195-
if (PBD && inferFinalAndDiagnoseIfNeeded(decl, PBD->getStaticSpelling()))
1199+
if (PBD && inferFinalAndDiagnoseIfNeeded(decl, cls, PBD->getStaticSpelling()))
11961200
return true;
11971201

11981202
if (VD->isLet()) {
@@ -1217,7 +1221,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12171221
case DeclKind::Func: {
12181222
// Methods declared 'static' are final.
12191223
auto staticSpelling = cast<FuncDecl>(decl)->getStaticSpelling();
1220-
if (inferFinalAndDiagnoseIfNeeded(decl, staticSpelling))
1224+
if (inferFinalAndDiagnoseIfNeeded(decl, cls, staticSpelling))
12211225
return true;
12221226
break;
12231227
}
@@ -1228,9 +1232,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12281232
case AccessorKind::DidSet:
12291233
case AccessorKind::WillSet:
12301234
// Observing accessors are marked final if in a class.
1231-
if (accessor->getDeclContext()->getSelfClassDecl())
1232-
return true;
1233-
break;
1235+
return true;
12341236

12351237
case AccessorKind::Read:
12361238
case AccessorKind::Modify:
@@ -1252,7 +1254,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12521254
case DeclKind::Subscript: {
12531255
// Member subscripts.
12541256
auto staticSpelling = cast<SubscriptDecl>(decl)->getStaticSpelling();
1255-
if (inferFinalAndDiagnoseIfNeeded(decl, staticSpelling))
1257+
if (inferFinalAndDiagnoseIfNeeded(decl, cls, staticSpelling))
12561258
return true;
12571259
break;
12581260
}

0 commit comments

Comments
 (0)