@@ -2809,7 +2809,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
28092809
28102810 static bool isEffectAnchor (Expr *e) {
28112811 return isa<AbstractClosureExpr>(e) || isa<DiscardAssignmentExpr>(e) ||
2812- isa<AssignExpr>(e);
2812+ isa<AssignExpr>(e) || (isa<DeclRefExpr>(e) && e-> isImplicit ()) ;
28132813 }
28142814
28152815 static bool isAnchorTooEarly (Expr *e) {
@@ -3589,27 +3589,43 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
35893589 Ctx.Diags .diagnose (E->getAwaitLoc (), diag::no_async_in_await);
35903590 }
35913591
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 {
35973594 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))
35993597 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 ()))
36023601 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+ }
36033611 }
3612+ return std::make_pair (awaitInsertLoc, insertText);
3613+ }
36043614
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);
36053621 bool downgradeToWarning = llvm::all_of (errors,
36063622 [&](DiagnosticInfo diag) -> bool {
36073623 return diag.downgradeToWarning ;
36083624 });
36093625
36103626 Ctx.Diags .diagnose (anchor->getStartLoc (), diag::async_expr_without_await)
36113627 .warnUntilSwiftVersionIf (downgradeToWarning, 6 )
3612- .fixItInsert (awaitInsertLoc, " await " )
3628+ .fixItInsert (loc, insertText )
36133629 .highlight (anchor->getSourceRange ());
36143630
36153631 for (const DiagnosticInfo &diag: errors) {
0 commit comments