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