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