@@ -2801,7 +2801,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
28012801
28022802 static bool isEffectAnchor (Expr *e) {
28032803 return isa<AbstractClosureExpr>(e) || isa<DiscardAssignmentExpr>(e) ||
2804- isa<AssignExpr>(e);
2804+ isa<AssignExpr>(e) || (isa<DeclRefExpr>(e) && e-> isImplicit ()) ;
28052805 }
28062806
28072807 static bool isAnchorTooEarly (Expr *e) {
@@ -3581,27 +3581,43 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
35813581 Ctx.Diags .diagnose (E->getAwaitLoc (), diag::no_async_in_await);
35823582 }
35833583
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 {
35893586 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))
35913589 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 ()))
35943593 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+ }
35953603 }
3604+ return std::make_pair (awaitInsertLoc, insertText);
3605+ }
35963606
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);
35973613 bool downgradeToWarning = llvm::all_of (errors,
35983614 [&](DiagnosticInfo diag) -> bool {
35993615 return diag.downgradeToWarning ;
36003616 });
36013617
36023618 Ctx.Diags .diagnose (anchor->getStartLoc (), diag::async_expr_without_await)
36033619 .warnUntilSwiftVersionIf (downgradeToWarning, 6 )
3604- .fixItInsert (awaitInsertLoc, " await " )
3620+ .fixItInsert (loc, insertText )
36053621 .highlight (anchor->getSourceRange ());
36063622
36073623 for (const DiagnosticInfo &diag: errors) {
0 commit comments