@@ -2800,8 +2800,11 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2800
2800
llvm::DenseMap<Expr *, Expr *> parentMap;
2801
2801
2802
2802
static bool isEffectAnchor (Expr *e) {
2803
- return isa<AbstractClosureExpr>(e) || isa<DiscardAssignmentExpr>(e) ||
2804
- isa<AssignExpr>(e);
2803
+ return isa<AbstractClosureExpr>(e) ||
2804
+ isa<DiscardAssignmentExpr>(e) ||
2805
+ isa<AssignExpr>(e) ||
2806
+ isa<AnyTryExpr>(e) ||
2807
+ (isa<DeclRefExpr>(e) && e->isImplicit ());
2805
2808
}
2806
2809
2807
2810
static bool isAnchorTooEarly (Expr *e) {
@@ -3581,27 +3584,39 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
3581
3584
Ctx.Diags .diagnose (E->getAwaitLoc (), diag::no_async_in_await);
3582
3585
}
3583
3586
3587
+ std::pair<SourceLoc, std::string>
3588
+ getFixItForUncoveredAsyncSite (const Expr *anchor) const {
3589
+ SourceLoc awaitInsertLoc = anchor->getStartLoc ();
3590
+ std::string insertion = " await " ;
3591
+ if (const auto *tryExpr = dyn_cast<AnyTryExpr>(anchor))
3592
+ awaitInsertLoc = tryExpr->getSubExpr ()->getStartLoc ();
3593
+ // Supply a tailored fixIt including the identifier if we are
3594
+ // looking at a shorthand optional binding.
3595
+ else if (anchor->isImplicit ()) {
3596
+ if (auto declRef = dyn_cast<DeclRefExpr>(anchor))
3597
+ if (auto var = dyn_cast_or_null<VarDecl>(declRef->getDecl ())) {
3598
+ insertion = " = await " + var->getNameStr ().str ();
3599
+ awaitInsertLoc = Lexer
3600
+ ::getLocForEndOfToken (Ctx.Diags.SourceMgr, anchor->getStartLoc ());
3601
+ }
3602
+ }
3603
+ return std::make_pair(awaitInsertLoc, insertion);
3604
+ }
3605
+
3584
3606
void diagnoseUncoveredAsyncSite (const Expr *anchor) const {
3585
3607
auto asyncPointIter = uncoveredAsync.find (anchor);
3586
3608
if (asyncPointIter == uncoveredAsync.end ())
3587
3609
return ;
3588
3610
const std::vector<DiagnosticInfo> &errors = asyncPointIter->getSecond ();
3589
- SourceLoc awaitInsertLoc = anchor->getStartLoc ();
3590
- if (const AnyTryExpr *tryExpr = dyn_cast<AnyTryExpr>(anchor))
3591
- awaitInsertLoc = tryExpr->getSubExpr ()->getStartLoc ();
3592
- else if (const AutoClosureExpr *autoClosure = dyn_cast<AutoClosureExpr>(anchor)) {
3593
- if (const AnyTryExpr *tryExpr = dyn_cast<AnyTryExpr>(autoClosure->getSingleExpressionBody ()))
3594
- awaitInsertLoc = tryExpr->getSubExpr ()->getStartLoc ();
3595
- }
3596
-
3611
+ const auto fixIt = getFixItForUncoveredAsyncSite (anchor);
3597
3612
bool downgradeToWarning = llvm::all_of (errors,
3598
3613
[&](DiagnosticInfo diag) -> bool {
3599
3614
return diag.downgradeToWarning ;
3600
3615
});
3601
3616
3602
3617
Ctx.Diags .diagnose (anchor->getStartLoc (), diag::async_expr_without_await)
3603
3618
.warnUntilSwiftVersionIf (downgradeToWarning, 6 )
3604
- .fixItInsert (awaitInsertLoc, " await " )
3619
+ .fixItInsert (fixIt. first , fixIt. second )
3605
3620
.highlight (anchor->getSourceRange ());
3606
3621
3607
3622
for (const DiagnosticInfo &diag: errors) {
0 commit comments