Skip to content

Commit ff371f9

Browse files
authored
Merge pull request #69600 from tshortli/module-interface-lazy-typecheck-has-storage
AST: Trigger HasStorageRequest when retrieving semantic attributes
2 parents b7d8a9b + 4eb8ed7 commit ff371f9

File tree

10 files changed

+54
-21
lines changed

10 files changed

+54
-21
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5374,6 +5374,7 @@ class BuiltinTupleDecl final : public NominalTypeDecl {
53745374
/// AbstractStorageDecl - This is the common superclass for VarDecl and
53755375
/// SubscriptDecl, representing potentially settable memory locations.
53765376
class AbstractStorageDecl : public ValueDecl {
5377+
friend class HasStorageRequest;
53775378
friend class SetterAccessLevelRequest;
53785379
friend class IsGetterMutatingRequest;
53795380
friend class IsSetterMutatingRequest;
@@ -5440,6 +5441,8 @@ class AbstractStorageDecl : public ValueDecl {
54405441
llvm::PointerIntPair<AccessorRecord*, 3, OptionalEnum<AccessLevel>> Accessors;
54415442

54425443
struct {
5444+
unsigned HasStorageComputed : 1;
5445+
unsigned HasStorage : 1;
54435446
unsigned IsGetterMutatingComputed : 1;
54445447
unsigned IsGetterMutating : 1;
54455448
unsigned IsSetterMutatingComputed : 1;
@@ -5509,7 +5512,6 @@ class AbstractStorageDecl : public ValueDecl {
55095512
return getImplInfo().getReadWriteImpl();
55105513
}
55115514

5512-
55135515
/// Return true if this is a VarDecl that has storage associated with
55145516
/// it.
55155517
bool hasStorage() const;

include/swift/AST/TypeCheckRequests.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,10 +1779,9 @@ class MemberwiseInitPropertiesRequest :
17791779
bool isCached() const { return true; }
17801780
};
17811781

1782-
class HasStorageRequest :
1783-
public SimpleRequest<HasStorageRequest,
1784-
bool(AbstractStorageDecl *),
1785-
RequestFlags::Cached> {
1782+
class HasStorageRequest
1783+
: public SimpleRequest<HasStorageRequest, bool(AbstractStorageDecl *),
1784+
RequestFlags::SeparatelyCached> {
17861785
public:
17871786
using SimpleRequest::SimpleRequest;
17881787

@@ -1793,7 +1792,10 @@ class HasStorageRequest :
17931792
bool evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
17941793

17951794
public:
1795+
// Separate caching.
17961796
bool isCached() const { return true; }
1797+
llvm::Optional<bool> getCachedResult() const;
1798+
void cacheResult(bool hasStorage) const;
17971799
};
17981800

17991801
class StorageImplInfoRequest :

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ SWIFT_REQUEST(TypeChecker, StorageImplInfoRequest,
311311
StorageImplInfo(AbstractStorageDecl *), SeparatelyCached,
312312
NoLocationInfo)
313313
SWIFT_REQUEST(TypeChecker, HasStorageRequest,
314-
bool(AbstractStorageDecl *), Cached,
314+
bool(AbstractStorageDecl *), SeparatelyCached,
315315
NoLocationInfo)
316316
SWIFT_REQUEST(TypeChecker, StoredPropertiesAndMissingMembersRequest,
317317
ArrayRef<Decl *>(NominalTypeDecl *), Cached, NoLocationInfo)

lib/AST/Decl.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6743,13 +6743,11 @@ void AbstractStorageDecl::setImplInfo(StorageImplInfo implInfo) {
67436743
cacheImplInfo(implInfo);
67446744

67456745
if (isImplicit()) {
6746-
auto &evaluator = getASTContext().evaluator;
6747-
HasStorageRequest request{this};
6748-
if (!evaluator.hasCachedResult(request))
6749-
evaluator.cacheOutput(request, implInfo.hasStorage());
6750-
else {
6751-
assert(
6752-
evaluateOrDefault(evaluator, request, false) == implInfo.hasStorage());
6746+
if (!LazySemanticInfo.HasStorageComputed) {
6747+
LazySemanticInfo.HasStorageComputed = true;
6748+
LazySemanticInfo.HasStorage = implInfo.hasStorage();
6749+
} else {
6750+
assert(LazySemanticInfo.HasStorage == implInfo.hasStorage());
67536751
}
67546752
}
67556753
}

lib/AST/TypeCheckRequests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,7 +2077,10 @@ DeclAttributes SemanticDeclAttrsRequest::evaluate(Evaluator &evaluator,
20772077
// Trigger requests that cause additional semantic attributes to be added.
20782078
if (auto afd = dyn_cast<AbstractFunctionDecl>(decl)) {
20792079
(void)afd->isTransparent();
2080+
} else if (auto asd = dyn_cast<AbstractStorageDecl>(decl)) {
2081+
(void)asd->hasStorage();
20802082
}
2083+
20812084
return decl->getAttrs();
20822085
}
20832086

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,11 +2331,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23312331
this->visitBoundVariable(var);
23322332
});
23332333

2334-
// Add the '@_hasStorage' attribute if this property is stored.
2335-
if (VD->hasStorage() && !VD->getAttrs().hasAttribute<HasStorageAttr>())
2336-
VD->getAttrs().add(new (getASTContext())
2337-
HasStorageAttr(/*isImplicit=*/true));
2338-
23392334
// Reject cases where this is a variable that has storage but it isn't
23402335
// allowed.
23412336
if (VD->hasStorage()) {

lib/Sema/TypeCheckStorage.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3585,6 +3585,29 @@ bool HasStorageRequest::evaluate(Evaluator &evaluator,
35853585
return hasStorage;
35863586
}
35873587

3588+
llvm::Optional<bool> HasStorageRequest::getCachedResult() const {
3589+
AbstractStorageDecl *decl = std::get<0>(getStorage());
3590+
if (decl->LazySemanticInfo.HasStorageComputed)
3591+
return static_cast<bool>(decl->LazySemanticInfo.HasStorage);
3592+
return llvm::None;
3593+
}
3594+
3595+
void HasStorageRequest::cacheResult(bool hasStorage) const {
3596+
AbstractStorageDecl *decl = std::get<0>(getStorage());
3597+
decl->LazySemanticInfo.HasStorageComputed = true;
3598+
decl->LazySemanticInfo.HasStorage = hasStorage;
3599+
3600+
// Add an attribute for printing, but only to VarDecls.
3601+
if (isa<ParamDecl>(decl))
3602+
return;
3603+
3604+
if (auto varDecl = dyn_cast<VarDecl>(decl)) {
3605+
if (hasStorage && !varDecl->getAttrs().hasAttribute<HasStorageAttr>())
3606+
varDecl->getAttrs().add(new (varDecl->getASTContext())
3607+
HasStorageAttr(/*isImplicit=*/true));
3608+
}
3609+
}
3610+
35883611
StorageImplInfo
35893612
StorageImplInfoRequest::evaluate(Evaluator &evaluator,
35903613
AbstractStorageDecl *storage) const {
@@ -3598,7 +3621,7 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
35983621
if (auto *var = dyn_cast<VarDecl>(storage)) {
35993622
// Allow the @_hasStorage attribute to override all the accessors we parsed
36003623
// when making the final classification.
3601-
if (var->getAttrs().hasAttribute<HasStorageAttr>()) {
3624+
if (var->getParsedAttrs().hasAttribute<HasStorageAttr>()) {
36023625
// The SIL rules for @_hasStorage are slightly different from the non-SIL
36033626
// rules. In SIL mode, @_hasStorage marks that the type is simply stored,
36043627
// and the only thing that determines mutability is the existence of the

test/Inputs/lazy_typecheck.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ public struct PublicGenericStruct<T> {
167167
}
168168
}
169169

170+
@frozen public struct FrozenPublicStruct {
171+
private(set) var varWithPrivateSetter: Int = 1
172+
173+
public init(_ varWithPrivateSetter: Int) {
174+
self.varWithPrivateSetter = varWithPrivateSetter
175+
}
176+
}
177+
170178
struct InternalStruct: NoTypecheckProto {
171179
var x: NoTypecheck
172180

test/Inputs/lazy_typecheck_client.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func testGobalVars() {
3232
let _: (Int, Int) = (publicGlobalVarInferredTuplePatX, publicGlobalVarInferredTuplePatY)
3333
}
3434

35-
func testPublicStruct() {
35+
func testPublicStructs() {
3636
let s = PublicStruct(x: 1)
3737
let _: Int = s.publicMethod()
3838
let _: Int = s.publicProperty
@@ -42,6 +42,8 @@ func testPublicStruct() {
4242
let _: Int = s.publicTransparentProperty
4343
PublicStruct.publicStaticMethod()
4444
PublicStruct.activeMethod()
45+
46+
let _ = FrozenPublicStruct(1)
4547
}
4648

4749
func testPublicClasses() {

test/attr/attr_objc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ class infer_instanceVar1 {
983983

984984
@objc // access-note-move{{infer_instanceVar1.observingAccessorsVar1_}}
985985
var observingAccessorsVar1_: Int {
986-
// CHECK: {{^}} @objc @_hasStorage var observingAccessorsVar1_: Int {
986+
// CHECK: {{^}} {{@_hasStorage @objc|@objc @_hasStorage}} var observingAccessorsVar1_: Int {
987987
willSet {}
988988
// CHECK-NEXT: {{^}} @objc get {
989989
// CHECK-NEXT: return

0 commit comments

Comments
 (0)