Skip to content

Commit 90f6363

Browse files
authored
Merge pull request #25426 from slavapestov/final-request-cleanup
Small IsFinalRequest cleanup
2 parents d3785d9 + 95c221a commit 90f6363

File tree

6 files changed

+55
-53
lines changed

6 files changed

+55
-53
lines changed

include/swift/AST/Decl.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,8 @@ class alignas(1 << DeclAlignInBits) Decl {
387387
/// It is up to the debugger to instruct SIL how to access this variable.
388388
IsDebuggerVar : 1,
389389

390-
/// Whether this is a property defined in the debugger's REPL.
391-
/// FIXME: Remove this once LLDB has proper support for resilience.
392-
IsREPLVar : 1,
390+
/// Whether this is the backing storage for a lazy property.
391+
IsLazyStorageProperty : 1,
393392

394393
/// Whether this is the backing storage for a property wrapper.
395394
IsPropertyWrapperBackingProperty : 1
@@ -4806,7 +4805,7 @@ class VarDecl : public AbstractStorageDecl {
48064805
Bits.VarDecl.Specifier = static_cast<unsigned>(Sp);
48074806
Bits.VarDecl.IsCaptureList = IsCaptureList;
48084807
Bits.VarDecl.IsDebuggerVar = false;
4809-
Bits.VarDecl.IsREPLVar = false;
4808+
Bits.VarDecl.IsLazyStorageProperty = false;
48104809
Bits.VarDecl.HasNonPatternBindingInit = false;
48114810
Bits.VarDecl.IsPropertyWrapperBackingProperty = false;
48124811
}
@@ -5095,12 +5094,13 @@ class VarDecl : public AbstractStorageDecl {
50955094
void setDebuggerVar(bool IsDebuggerVar) {
50965095
Bits.VarDecl.IsDebuggerVar = IsDebuggerVar;
50975096
}
5098-
5099-
/// Is this a special debugger REPL variable?
5100-
/// FIXME: Remove this once LLDB has proper support for resilience.
5101-
bool isREPLVar() const { return Bits.VarDecl.IsREPLVar; }
5102-
void setREPLVar(bool IsREPLVar) {
5103-
Bits.VarDecl.IsREPLVar = IsREPLVar;
5097+
5098+
/// Is this the synthesized storage for a 'lazy' property?
5099+
bool isLazyStorageProperty() const {
5100+
return Bits.VarDecl.IsLazyStorageProperty;
5101+
}
5102+
void setLazyStorageProperty(bool IsLazyStorage) {
5103+
Bits.VarDecl.IsLazyStorageProperty = IsLazyStorage;
51045104
}
51055105

51065106
/// Retrieve the custom attribute that attaches a property wrapper to this

lib/Sema/CodeSynthesis.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,9 @@ void swift::completeLazyVarImplementation(VarDecl *VD) {
16251625
StorageName,
16261626
VD->getDeclContext());
16271627
Storage->setInterfaceType(StorageInterfaceTy);
1628+
Storage->setLazyStorageProperty(true);
16281629
Storage->setUserAccessible(false);
1630+
16291631
addMemberToContextIfNeeded(Storage, VD->getDeclContext(), VD);
16301632

16311633
// Create the pattern binding decl for the storage decl. This will get
@@ -1642,12 +1644,7 @@ void swift::completeLazyVarImplementation(VarDecl *VD) {
16421644
VD->getGetter()->setBodySynthesizer(&synthesizeLazyGetterBody, Storage);
16431645
VD->getSetter()->setBodySynthesizer(&synthesizeLazySetterBody, Storage);
16441646

1645-
// Mark the vardecl to be final, implicit, and private. In a class, this
1646-
// prevents it from being dynamically dispatched. Note that we do this after
1647-
// the accessors are set up, because we don't want the setter for the lazy
1648-
// property to inherit these properties from the storage.
1649-
if (VD->getDeclContext()->getSelfClassDecl())
1650-
makeFinal(Context, Storage);
1647+
// The storage is implicit and private.
16511648
Storage->setImplicit();
16521649
Storage->overwriteAccess(AccessLevel::Private);
16531650
Storage->overwriteSetterAccess(AccessLevel::Private);
@@ -1796,6 +1793,11 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
17961793
if (isInvalid)
17971794
backingVar->setInvalid();
17981795
backingVar->setOriginalWrappedProperty(var);
1796+
1797+
// The backing storage is 'private'.
1798+
backingVar->overwriteAccess(AccessLevel::Private);
1799+
backingVar->overwriteSetterAccess(AccessLevel::Private);
1800+
17991801
addMemberToContextIfNeeded(backingVar, dc, var);
18001802

18011803
// Create the pattern binding declaration for the backing property.
@@ -1819,15 +1821,6 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
18191821

18201822
tc.typeCheckPatternBinding(parentPBD, patternNumber);
18211823
}
1822-
// Mark the backing property as 'final'. There's no sensible way to override.
1823-
if (dc->getSelfClassDecl())
1824-
makeFinal(ctx, backingVar);
1825-
1826-
// The backing storage is 'private'.
1827-
backingVar->overwriteAccess(AccessLevel::Private);
1828-
1829-
// Determine setter access.
1830-
backingVar->overwriteSetterAccess(AccessLevel::Private);
18311824

18321825
Expr *originalInitialValue = nullptr;
18331826
if (Expr *init = parentPBD->getInit(patternNumber)) {

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 & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,13 +1050,6 @@ static void validatePatternBindingEntries(TypeChecker &tc,
10501050
validatePatternBindingEntry(tc, binding, i);
10511051
}
10521052

1053-
void swift::makeFinal(ASTContext &ctx, ValueDecl *D) {
1054-
if (D && !D->isFinal()) {
1055-
assert(isa<ClassDecl>(D) || D->isPotentiallyOverridable());
1056-
D->getAttrs().add(new (ctx) FinalAttr(/*IsImplicit=*/true));
1057-
}
1058-
}
1059-
10601053
namespace {
10611054
// The raw values of this enum must be kept in sync with
10621055
// diag::implicitly_final_cannot_be_open.
@@ -1070,12 +1063,8 @@ enum class ImplicitlyFinalReason : unsigned {
10701063
};
10711064
}
10721065

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

11871176
llvm::Expected<bool>
11881177
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+
11891185
switch (decl->getKind()) {
11901186
case DeclKind::Var: {
11911187
// Properties are final if they are declared 'static' or a 'let'
11921188
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+
11931195
if (auto *nominalDecl = VD->getDeclContext()->getSelfClassDecl()) {
11941196
// If this variable is a class member, mark it final if the
11951197
// class is final, or if it was declared with 'let'.
11961198
auto *PBD = VD->getParentPatternBinding();
1197-
if (PBD && inferFinalAndDiagnoseIfNeeded(decl, PBD->getStaticSpelling()))
1199+
if (PBD && inferFinalAndDiagnoseIfNeeded(decl, cls, PBD->getStaticSpelling()))
11981200
return true;
11991201

12001202
if (VD->isLet()) {
@@ -1219,7 +1221,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12191221
case DeclKind::Func: {
12201222
// Methods declared 'static' are final.
12211223
auto staticSpelling = cast<FuncDecl>(decl)->getStaticSpelling();
1222-
if (inferFinalAndDiagnoseIfNeeded(decl, staticSpelling))
1224+
if (inferFinalAndDiagnoseIfNeeded(decl, cls, staticSpelling))
12231225
return true;
12241226
break;
12251227
}
@@ -1230,9 +1232,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12301232
case AccessorKind::DidSet:
12311233
case AccessorKind::WillSet:
12321234
// Observing accessors are marked final if in a class.
1233-
if (accessor->getDeclContext()->getSelfClassDecl())
1234-
return true;
1235-
break;
1235+
return true;
12361236

12371237
case AccessorKind::Read:
12381238
case AccessorKind::Modify:
@@ -1254,7 +1254,7 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
12541254
case DeclKind::Subscript: {
12551255
// Member subscripts.
12561256
auto staticSpelling = cast<SubscriptDecl>(decl)->getStaticSpelling();
1257-
if (inferFinalAndDiagnoseIfNeeded(decl, staticSpelling))
1257+
if (inferFinalAndDiagnoseIfNeeded(decl, cls, staticSpelling))
12581258
return true;
12591259
break;
12601260
}

test/SILGen/lazy_properties.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,15 @@ func test21057425() {
3434
struct HasAnonymousParameters {
3535
lazy var x = { $0 }(0)
3636
}
37+
38+
class LazyClass {
39+
lazy var x = 0
40+
}
41+
42+
// CHECK-LABEL: sil hidden [ossa] @$s15lazy_properties9LazyClassC1xSivg : $@convention(method) (@guaranteed LazyClass) -> Int
43+
// CHECK: ref_element_addr %0 : $LazyClass, #LazyClass.$__lazy_storage_$_x
44+
// CHECK: return
45+
46+
// CHECK-LABEL: sil hidden [ossa] @$s15lazy_properties9LazyClassC1xSivs : $@convention(method) (Int, @guaranteed LazyClass) -> ()
47+
// CHECK: ref_element_addr %1 : $LazyClass, #LazyClass.$__lazy_storage_$_x
48+
// CHECK: return

test/SILGen/property_wrappers.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class ClassUsingWrapper {
264264
extension ClassUsingWrapper {
265265
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers17ClassUsingWrapperC04testcdE01cyAC_tF : $@convention(method) (@guaranteed ClassUsingWrapper, @guaranteed ClassUsingWrapper) -> () {
266266
func testClassUsingWrapper(c: ClassUsingWrapper) {
267-
// CHECK: class_method [[GETTER:%.*]] : $ClassUsingWrapper, #ClassUsingWrapper.$x!getter.1
267+
// CHECK: ref_element_addr %1 : $ClassUsingWrapper, #ClassUsingWrapper.$x
268268
self.$x.test()
269269
}
270270
}
@@ -298,9 +298,9 @@ class UseWrapperWithDefaultInit {
298298

299299

300300
// CHECK-LABEL: sil_vtable ClassUsingWrapper {
301-
// CHECK: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter
302-
// CHECK: #ClassUsingWrapper.x!setter.1: (ClassUsingWrapper) -> (Int) -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivs // ClassUsingWrapper.x.setter
303-
// CHECK: #ClassUsingWrapper.x!modify.1: (ClassUsingWrapper) -> () -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivM // ClassUsingWrapper.x.modify
304-
// CHECK: #ClassUsingWrapper.$x!getter.1: (ClassUsingWrapper) -> () -> WrapperWithInitialValue<Int> : @$s17property_wrappers17ClassUsingWrapperC2$x33_{{.*}}16WithInitialValueVySiGvg // ClassUsingWrapper.$x.getter
305-
// CHECK: #ClassUsingWrapper.$x!setter.1: (ClassUsingWrapper) -> (WrapperWithInitialValue<Int>) -> () : @$s17property_wrappers17ClassUsingWrapperC2$x33_{{.*}}16WithInitialValueVySiGvs // ClassUsingWrapper.$x.setter
306-
// CHECK: #ClassUsingWrapper.$x!modify.1: (ClassUsingWrapper) -> () -> () : @$s17property_wrappers17ClassUsingWrapperC2$x33_{{.*}}16WithInitialValueVySiGvM // ClassUsingWrapper.$x.modify
301+
// CHECK-NEXT: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter
302+
// CHECK-NEXT: #ClassUsingWrapper.x!setter.1: (ClassUsingWrapper) -> (Int) -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivs // ClassUsingWrapper.x.setter
303+
// CHECK-NEXT: #ClassUsingWrapper.x!modify.1: (ClassUsingWrapper) -> () -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivM // ClassUsingWrapper.x.modify
304+
// CHECK-NEXT: #ClassUsingWrapper.init!allocator.1: (ClassUsingWrapper.Type) -> () -> ClassUsingWrapper : @$s17property_wrappers17ClassUsingWrapperCACycfC
305+
// CHECK-NEXT: #ClassUsingWrapper.deinit!deallocator.1: @$s17property_wrappers17ClassUsingWrapperCfD
306+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)