15
15
// ===----------------------------------------------------------------------===//
16
16
#include " TypeCheckConcurrency.h"
17
17
#include " TypeCheckDistributed.h"
18
+ #include " TypeCheckInvertible.h"
18
19
#include " TypeChecker.h"
19
20
#include " TypeCheckType.h"
20
21
#include " swift/Strings.h"
@@ -1113,10 +1114,6 @@ void swift::diagnoseMissingSendableConformance(
1113
1114
}
1114
1115
1115
1116
namespace {
1116
- template <typename Visitor>
1117
- bool visitInstanceStorage (
1118
- NominalTypeDecl *nominal, DeclContext *dc, Visitor &visitor);
1119
-
1120
1117
// / Infer Sendable from the instance storage of the given nominal type.
1121
1118
// / \returns \c llvm::None if there is no way to make the type \c Sendable,
1122
1119
// / \c true if \c Sendable needs to be @unchecked, \c false if it can be
@@ -1131,20 +1128,22 @@ namespace {
1131
1128
}
1132
1129
}
1133
1130
1134
- struct Visitor {
1131
+ class Visitor : public StorageVisitor {
1132
+ public:
1135
1133
NominalTypeDecl *nominal;
1136
1134
SmallVectorImpl<Requirement> &requirements;
1137
1135
bool isUnchecked = false ;
1138
1136
ProtocolDecl *sendableProto = nullptr ;
1139
1137
1140
1138
Visitor (
1141
1139
NominalTypeDecl *nominal, SmallVectorImpl<Requirement> &requirements
1142
- ) : nominal(nominal), requirements(requirements) {
1140
+ ) : StorageVisitor(),
1141
+ nominal (nominal), requirements(requirements) {
1143
1142
ASTContext &ctx = nominal->getASTContext ();
1144
1143
sendableProto = ctx.getProtocol (KnownProtocolKind::Sendable);
1145
1144
}
1146
1145
1147
- bool operator ()(VarDecl *var, Type propertyType) {
1146
+ bool operator ()(VarDecl *var, Type propertyType) override {
1148
1147
// If we have a class with mutable state, only an @unchecked
1149
1148
// conformance will work.
1150
1149
if (isa<ClassDecl>(nominal) && var->supportsMutation ())
@@ -1153,7 +1152,7 @@ namespace {
1153
1152
return checkType (propertyType);
1154
1153
}
1155
1154
1156
- bool operator ()(EnumElementDecl *element, Type elementType) {
1155
+ bool operator ()(EnumElementDecl *element, Type elementType) override {
1157
1156
return checkType (elementType);
1158
1157
}
1159
1158
@@ -1195,7 +1194,7 @@ namespace {
1195
1194
}
1196
1195
} visitor(nominal, requirements);
1197
1196
1198
- return visitInstanceStorage (nominal, nominal, visitor );
1197
+ return visitor.visit (nominal, nominal);
1199
1198
}
1200
1199
}
1201
1200
@@ -4823,53 +4822,6 @@ bool swift::contextRequiresStrictConcurrencyChecking(
4823
4822
return false ;
4824
4823
}
4825
4824
4826
- namespace {
4827
- // / Visit the instance storage of the given nominal type as seen through
4828
- // / the given declaration context.
4829
- // /
4830
- // / \param visitor Called with each (stored property, property type) pair
4831
- // / for classes/structs and with each (enum element, associated value type)
4832
- // / pair for enums.
4833
- // /
4834
- // / \returns \c true if any call to the \c visitor returns \c true, and
4835
- // / \c false otherwise.
4836
- template <typename Visitor>
4837
- bool visitInstanceStorage (
4838
- NominalTypeDecl *nominal, DeclContext *dc, Visitor &visitor) {
4839
- // Walk the stored properties of classes and structs.
4840
- if (isa<StructDecl>(nominal) || isa<ClassDecl>(nominal)) {
4841
- for (auto property : nominal->getStoredProperties ()) {
4842
- auto propertyType = dc->mapTypeIntoContext (property->getInterfaceType ())
4843
- ->getRValueType ()->getReferenceStorageReferent ();
4844
- if (visitor (property, propertyType))
4845
- return true ;
4846
- }
4847
-
4848
- return false ;
4849
- }
4850
-
4851
- // Walk the enum elements that have associated values.
4852
- if (auto enumDecl = dyn_cast<EnumDecl>(nominal)) {
4853
- for (auto caseDecl : enumDecl->getAllCases ()) {
4854
- for (auto element : caseDecl->getElements ()) {
4855
- if (!element->hasAssociatedValues ())
4856
- continue ;
4857
-
4858
- // Check that the associated value type is Sendable.
4859
- auto elementType = dc->mapTypeIntoContext (
4860
- element->getArgumentInterfaceType ());
4861
- if (visitor (element, elementType))
4862
- return true ;
4863
- }
4864
- }
4865
-
4866
- return false ;
4867
- }
4868
-
4869
- return false ;
4870
- }
4871
- }
4872
-
4873
4825
// / Check the instance storage of the given nominal type to verify whether
4874
4826
// / it is comprised only of Sendable instance storage.
4875
4827
static bool checkSendableInstanceStorage (
@@ -4891,19 +4843,20 @@ static bool checkSendableInstanceStorage(
4891
4843
4892
4844
// Stored properties of structs and classes must have
4893
4845
// Sendable-conforming types.
4894
- struct Visitor {
4846
+ class Visitor : public StorageVisitor {
4847
+ public:
4895
4848
bool invalid = false ;
4896
4849
NominalTypeDecl *nominal;
4897
4850
DeclContext *dc;
4898
4851
SendableCheck check;
4899
4852
const LangOptions &langOpts;
4900
4853
4901
4854
Visitor (NominalTypeDecl *nominal, DeclContext *dc, SendableCheck check)
4902
- : nominal(nominal), dc(dc), check(check),
4855
+ : StorageVisitor(), nominal(nominal), dc(dc), check(check),
4903
4856
langOpts (nominal->getASTContext ().LangOpts) { }
4904
4857
4905
4858
// / Handle a stored property.
4906
- bool operator ()(VarDecl *property, Type propertyType) {
4859
+ bool operator ()(VarDecl *property, Type propertyType) override {
4907
4860
// Classes with mutable properties are not Sendable.
4908
4861
if (property->supportsMutation () && isa<ClassDecl>(nominal)) {
4909
4862
if (isImplicitSendableCheck (check)) {
@@ -4958,7 +4911,7 @@ static bool checkSendableInstanceStorage(
4958
4911
}
4959
4912
4960
4913
// / Handle an enum associated value.
4961
- bool operator ()(EnumElementDecl *element, Type elementType) {
4914
+ bool operator ()(EnumElementDecl *element, Type elementType) override {
4962
4915
diagnoseNonSendableTypes (
4963
4916
elementType, SendableCheckContext (dc, check), element->getLoc (),
4964
4917
[&](Type type, DiagnosticBehavior behavior) {
@@ -4993,7 +4946,7 @@ static bool checkSendableInstanceStorage(
4993
4946
}
4994
4947
} visitor(nominal, dc, check);
4995
4948
4996
- return visitInstanceStorage (nominal, dc, visitor ) || visitor.invalid;
4949
+ return visitor.visit (nominal, dc) || visitor.invalid;
4997
4950
}
4998
4951
4999
4952
bool swift::checkSendableConformance (
0 commit comments