@@ -67,87 +67,56 @@ void checkImplicitCopyReturnType(const ClosureExpr *Closure,
67
67
}
68
68
}
69
69
70
- class CheckExistentialAny : public TypeVisitor <CheckExistentialAny, bool > {
71
- public:
72
- static bool inType (Type type) {
73
- return CheckExistentialAny ().visit (type->getCanonicalType ());
74
- }
75
-
76
- static void inFunctionReturnType (FuncDecl *FD, DiagnosticEngine &Diags) {
77
- Type T = FD->getResultInterfaceType ();
78
-
79
- if (inType (T))
80
- Diags.diagnose (FD, diag::perf_hint_func_returns_existential_any, FD);
81
- }
82
-
83
- static void inClosureReturnType (ClosureExpr *CE, DiagnosticEngine &Diags) {
84
- Type T = CE->getResultType ();
85
-
86
- if (inType (T))
87
- Diags.diagnose (CE->getLoc (),
88
- diag::perf_hint_closure_returns_existential_any);
89
- }
90
-
91
- static void inVariableType (const VarDecl *VD, DiagnosticEngine &Diags) {
92
- Type T = VD->getInterfaceType ();
70
+ bool isExistentialType (Type T) {
71
+ return dyn_cast<ExistentialType>(T) != nullptr ;
72
+ }
93
73
94
- if ( inType (T))
95
- Diags. diagnose (VD, diag::perf_hint_var_uses_existential_any, VD );
96
- }
74
+ bool hasExistentialAnyInType (Type type) {
75
+ return type-> getCanonicalType (). findIf (isExistentialType );
76
+ }
97
77
98
- static void inPatternType (const AnyPattern *AP, DiagnosticEngine &Diags) {
99
- Type T = AP->getType ();
78
+ void checkExistentialAnyInFunctionReturnType (FuncDecl *FD,
79
+ DiagnosticEngine &Diags) {
80
+ Type T = FD->getResultInterfaceType ();
100
81
101
- if (inType (T))
102
- Diags.diagnose (AP->getLoc (),
103
- diag::perf_hint_any_pattern_uses_existential_any);
104
- }
82
+ if (hasExistentialAnyInType (T))
83
+ Diags.diagnose (FD, diag::perf_hint_func_returns_existential_any, FD);
84
+ }
105
85
106
- static void inTypeAlias (const TypeAliasDecl *TAD, DiagnosticEngine &Diags) {
107
- Type T = TAD->getUnderlyingType ();
86
+ void checkExistentialAnyInClosureReturnType (ClosureExpr *CE,
87
+ DiagnosticEngine &Diags) {
88
+ Type T = CE->getResultType ();
108
89
109
- if (inType (T))
110
- Diags.diagnose (TAD ->getLoc (),
111
- diag::perf_hint_typealias_uses_existential_any, TAD );
112
- }
90
+ if (hasExistentialAnyInType (T))
91
+ Diags.diagnose (CE ->getLoc (),
92
+ diag::perf_hint_closure_returns_existential_any );
93
+ }
113
94
114
- bool visitExistentialType (ExistentialType *ET) {
115
- return true ;
116
- }
95
+ void checkExistentialAnyInVariableType ( const VarDecl *VD,
96
+ DiagnosticEngine &Diags) {
97
+ Type T = VD-> getInterfaceType ();
117
98
118
- bool visitTupleType (TupleType *TT) {
119
- for (const auto &element : TT->getElements ()) {
120
- if (visit (element.getType ())) {
121
- return true ;
122
- }
123
- }
124
- return false ;
125
- }
99
+ if (hasExistentialAnyInType (T))
100
+ Diags.diagnose (VD, diag::perf_hint_var_uses_existential_any, VD);
101
+ }
126
102
127
- bool visitBoundGenericType (BoundGenericType *BGT) {
128
- // Check generic arguments (e.g., Array<any Protocol>)
129
- for (Type arg : BGT->getGenericArgs ()) {
130
- if (visit (arg)) {
131
- return true ;
132
- }
133
- }
134
- return false ;
135
- }
103
+ void checkExistentialAnyInPatternType (const AnyPattern *AP,
104
+ DiagnosticEngine &Diags) {
105
+ Type T = AP->getType ();
136
106
137
- bool visitFunctionType (FunctionType *FT) {
138
- for (const auto ¶m : FT->getParams ()) {
139
- if (visit (param.getPlainType ()->getCanonicalType ())) {
140
- return true ;
141
- }
142
- }
107
+ if (hasExistentialAnyInType (T))
108
+ Diags.diagnose (AP->getLoc (),
109
+ diag::perf_hint_any_pattern_uses_existential_any);
110
+ }
143
111
144
- return visit (FT->getResult ()->getCanonicalType ());
145
- }
112
+ void checkExistentialAnyInTypeAlias (const TypeAliasDecl *TAD,
113
+ DiagnosticEngine &Diags) {
114
+ Type T = TAD->getUnderlyingType ();
146
115
147
- bool visitType (TypeBase *T) {
148
- return false ;
149
- }
150
- };
116
+ if ( hasExistentialAnyInType (T))
117
+ Diags. diagnose (TAD-> getLoc (),
118
+ diag::perf_hint_typealias_uses_existential_any, TAD);
119
+ }
151
120
152
121
// / Produce performance hint diagnostics for a SourceFile.
153
122
class PerformanceHintDiagnosticWalker final : public ASTWalker {
@@ -166,7 +135,7 @@ class PerformanceHintDiagnosticWalker final : public ASTWalker {
166
135
return Action::SkipNode (P);
167
136
168
137
if (const AnyPattern *AP = dyn_cast<AnyPattern>(P)) {
169
- CheckExistentialAny::inPatternType (AP, Ctx.Diags );
138
+ checkExistentialAnyInPatternType (AP, Ctx.Diags );
170
139
}
171
140
172
141
return Action::Continue (P);
@@ -189,7 +158,7 @@ class PerformanceHintDiagnosticWalker final : public ASTWalker {
189
158
" Traversing implicit expressions is disabled in the pre-walk visitor" );
190
159
191
160
if (auto Closure = dyn_cast<ClosureExpr>(E)) {
192
- CheckExistentialAny::inClosureReturnType (Closure, Ctx.Diags );
161
+ checkExistentialAnyInClosureReturnType (Closure, Ctx.Diags );
193
162
}
194
163
195
164
return Action::Continue (E);
@@ -202,9 +171,9 @@ class PerformanceHintDiagnosticWalker final : public ASTWalker {
202
171
if (const FuncDecl *FD = dyn_cast<FuncDecl>(D)) {
203
172
checkImplicitCopyReturnType (FD, Ctx.Diags );
204
173
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
205
- CheckExistentialAny::inVariableType (VD, Ctx.Diags );
174
+ checkExistentialAnyInVariableType (VD, Ctx.Diags );
206
175
} else if (const TypeAliasDecl *TAD = dyn_cast<TypeAliasDecl>(D)) {
207
- CheckExistentialAny::inTypeAlias (TAD, Ctx.Diags );
176
+ checkExistentialAnyInTypeAlias (TAD, Ctx.Diags );
208
177
}
209
178
210
179
return Action::Continue ();
@@ -216,7 +185,7 @@ class PerformanceHintDiagnosticWalker final : public ASTWalker {
216
185
" Traversing implicit declarations is disabled in the pre-walk visitor" );
217
186
218
187
if (auto *FD = dyn_cast<FuncDecl>(D)) {
219
- CheckExistentialAny::inFunctionReturnType (FD, Ctx.Diags );
188
+ checkExistentialAnyInFunctionReturnType (FD, Ctx.Diags );
220
189
}
221
190
222
191
return Action::Continue ();
0 commit comments