Skip to content

Commit 0fbbd89

Browse files
committedMar 25, 2021
Migrate checker to MiscDiagnostics
1 parent 5e17dc4 commit 0fbbd89

5 files changed

+67
-66
lines changed
 

‎lib/Sema/MiscDiagnostics.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/NameLookupRequests.h"
2525
#include "swift/AST/Pattern.h"
2626
#include "swift/AST/SourceFile.h"
27+
#include "swift/AST/TypeCheckRequests.h"
2728
#include "swift/Basic/Defer.h"
2829
#include "swift/Basic/SourceManager.h"
2930
#include "swift/Basic/Statistic.h"
@@ -4617,6 +4618,65 @@ static void diagnoseComparisonWithNaN(const Expr *E, const DeclContext *DC) {
46174618
const_cast<Expr *>(E)->walk(Walker);
46184619
}
46194620

4621+
namespace {
4622+
4623+
class CompletionHandlerUsageChecker final : public ASTWalker {
4624+
ASTContext &ctx;
4625+
4626+
public:
4627+
CompletionHandlerUsageChecker(ASTContext &ctx) : ctx(ctx) {}
4628+
4629+
bool walkToDeclPre(Decl *D) override { return !isa<PatternBindingDecl>(D); }
4630+
4631+
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
4632+
if (ClosureExpr *closure = dyn_cast<ClosureExpr>(expr))
4633+
return {closure->isBodyAsync(), closure};
4634+
4635+
if (ApplyExpr *call = dyn_cast<ApplyExpr>(expr)) {
4636+
if (DeclRefExpr *fnDeclExpr = dyn_cast<DeclRefExpr>(call->getFn())) {
4637+
ValueDecl *fnDecl = fnDeclExpr->getDecl();
4638+
CompletionHandlerAsyncAttr *asyncAltAttr =
4639+
fnDecl->getAttrs().getAttribute<CompletionHandlerAsyncAttr>();
4640+
if (asyncAltAttr) {
4641+
// Ensure that the attribute typechecks,
4642+
// this also resolves the async function decl.
4643+
if (!evaluateOrDefault(
4644+
ctx.evaluator,
4645+
TypeCheckCompletionHandlerAsyncAttrRequest{
4646+
cast<AbstractFunctionDecl>(fnDecl), asyncAltAttr},
4647+
false)) {
4648+
return {false, call};
4649+
}
4650+
ctx.Diags.diagnose(call->getLoc(), diag::warn_use_async_alternative);
4651+
ctx.Diags.diagnose(asyncAltAttr->AsyncFunctionDecl->getLoc(),
4652+
diag::decl_declared_here,
4653+
asyncAltAttr->AsyncFunctionDecl->getName());
4654+
}
4655+
}
4656+
}
4657+
return {true, expr};
4658+
}
4659+
};
4660+
4661+
} // namespace
4662+
4663+
void swift::checkFunctionAsyncUsage(AbstractFunctionDecl *decl) {
4664+
if (!decl->isAsyncContext())
4665+
return;
4666+
CompletionHandlerUsageChecker checker(decl->getASTContext());
4667+
BraceStmt *body = decl->getBody();
4668+
if (body)
4669+
body->walk(checker);
4670+
}
4671+
4672+
void swift::checkPatternBindingDeclAsyncUsage(PatternBindingDecl *decl) {
4673+
CompletionHandlerUsageChecker checker(decl->getASTContext());
4674+
for (Expr *init : decl->initializers()) {
4675+
if (auto closure = dyn_cast_or_null<ClosureExpr>(init))
4676+
closure->walk(checker);
4677+
}
4678+
}
4679+
46204680
//===----------------------------------------------------------------------===//
46214681
// High-level entry points.
46224682
//===----------------------------------------------------------------------===//

‎lib/Sema/MiscDiagnostics.h

+7
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ void fixItEncloseTrailingClosure(ASTContext &ctx,
108108
const CallExpr *call,
109109
Identifier closureLabel);
110110

111+
/// Check that we use the async version of a function where available
112+
///
113+
/// If a completion-handler function is called from an async context and it has
114+
/// a '@completionHandlerAsync' attribute, we emit a diagnostic suggesting the
115+
/// async call.
116+
void checkFunctionAsyncUsage(AbstractFunctionDecl *decl);
117+
void checkPatternBindingDeclAsyncUsage(PatternBindingDecl *decl);
111118
} // namespace swift
112119

113120
#endif // SWIFT_SEMA_MISC_DIAGNOSTICS_H

‎lib/Sema/TypeCheckConcurrency.cpp

-57
Original file line numberDiff line numberDiff line change
@@ -3087,60 +3087,3 @@ NormalProtocolConformance *GetImplicitSendableRequest::evaluate(
30873087

30883088
return conformance;
30893089
}
3090-
3091-
namespace {
3092-
class CompletionHandlerUsageChecker final : public ASTWalker {
3093-
ASTContext &ctx;
3094-
3095-
public:
3096-
CompletionHandlerUsageChecker(ASTContext &ctx) : ctx(ctx) {}
3097-
3098-
bool walkToDeclPre(Decl *D) override { return !isa<PatternBindingDecl>(D); }
3099-
3100-
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
3101-
if (ClosureExpr *closure = dyn_cast<ClosureExpr>(expr))
3102-
return {closure->isBodyAsync(), closure};
3103-
3104-
if (ApplyExpr *call = dyn_cast<ApplyExpr>(expr)) {
3105-
if (DeclRefExpr *fnDeclExpr = dyn_cast<DeclRefExpr>(call->getFn())) {
3106-
ValueDecl *fnDecl = fnDeclExpr->getDecl();
3107-
CompletionHandlerAsyncAttr *asyncAltAttr =
3108-
fnDecl->getAttrs().getAttribute<CompletionHandlerAsyncAttr>();
3109-
if (asyncAltAttr) {
3110-
// Ensure that the attribute typechecks,
3111-
// this also resolves the async function decl.
3112-
if (!evaluateOrDefault(
3113-
ctx.evaluator,
3114-
TypeCheckCompletionHandlerAsyncAttrRequest{
3115-
cast<AbstractFunctionDecl>(fnDecl), asyncAltAttr},
3116-
false)) {
3117-
return {false, call};
3118-
}
3119-
ctx.Diags.diagnose(call->getLoc(), diag::warn_use_async_alternative);
3120-
ctx.Diags.diagnose(asyncAltAttr->AsyncFunctionDecl->getLoc(),
3121-
diag::decl_declared_here,
3122-
asyncAltAttr->AsyncFunctionDecl->getName());
3123-
}
3124-
}
3125-
}
3126-
return {true, expr};
3127-
}
3128-
};
3129-
} // namespace
3130-
3131-
void swift::checkFunctionAsyncUsage(AbstractFunctionDecl *decl) {
3132-
if (!decl->isAsyncContext())
3133-
return;
3134-
CompletionHandlerUsageChecker checker(decl->getASTContext());
3135-
BraceStmt *body = decl->getBody();
3136-
if (body)
3137-
body->walk(checker);
3138-
}
3139-
3140-
void swift::checkPatternBindingDeclAsyncUsage(PatternBindingDecl *decl) {
3141-
CompletionHandlerUsageChecker checker(decl->getASTContext());
3142-
for (Expr *init : decl->initializers()) {
3143-
if (auto closure = dyn_cast_or_null<ClosureExpr>(init))
3144-
closure->walk(checker);
3145-
}
3146-
}

‎lib/Sema/TypeCheckConcurrency.h

-8
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,6 @@ Type getExplicitGlobalActor(ClosureExpr *closure);
238238
/// \returns true if an error occurred.
239239
bool checkSendableConformance(
240240
ProtocolConformance *conformance, SendableCheck check);
241-
242-
/// Check that we use the async version of a function where available
243-
///
244-
/// If a completion-handler function is called from an async context and it has
245-
/// a '@completionHandlerAsync' attribute, we emit a diagnostic suggesting the
246-
/// async call.
247-
void checkFunctionAsyncUsage(AbstractFunctionDecl *decl);
248-
void checkPatternBindingDeclAsyncUsage(PatternBindingDecl *decl);
249241
} // end namespace swift
250242

251243
#endif /* SWIFT_SEMA_TYPECHECKCONCURRENCY_H */

‎lib/Sema/TypeCheckConstraints.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
//===----------------------------------------------------------------------===//
1818

1919
#include "MiscDiagnostics.h"
20-
#include "TypeCheckConcurrency.h"
2120
#include "TypeChecker.h"
2221
#include "swift/AST/ASTVisitor.h"
2322
#include "swift/AST/ASTWalker.h"

0 commit comments

Comments
 (0)