@@ -1425,6 +1425,9 @@ class Context {
1425
1425
DiagnoseErrorOnTry = b;
1426
1426
}
1427
1427
1428
+ // / Stores the location of the innermost await
1429
+ SourceLoc awaitLoc = SourceLoc();
1430
+
1428
1431
// / Whether this is a function that rethrows.
1429
1432
bool hasPolymorphicEffect (EffectKind kind) const {
1430
1433
if (!Function)
@@ -1684,7 +1687,7 @@ class Context {
1684
1687
auto loc = E.getStartLoc ();
1685
1688
SourceLoc insertLoc;
1686
1689
SourceRange highlight;
1687
-
1690
+
1688
1691
// Generate more specific messages in some cases.
1689
1692
if (auto e = dyn_cast_or_null<ApplyExpr>(E.dyn_cast <Expr*>())) {
1690
1693
if (isa<PrefixUnaryExpr>(e) || isa<PostfixUnaryExpr>(e) ||
@@ -1694,7 +1697,7 @@ class Context {
1694
1697
}
1695
1698
insertLoc = loc;
1696
1699
highlight = e->getSourceRange ();
1697
-
1700
+
1698
1701
if (InterpolatedString &&
1699
1702
e->getCalledValue () &&
1700
1703
e->getCalledValue ()->getBaseName () ==
@@ -1703,7 +1706,7 @@ class Context {
1703
1706
insertLoc = InterpolatedString->getLoc ();
1704
1707
}
1705
1708
}
1706
-
1709
+
1707
1710
Diags.diagnose (loc, message).highlight (highlight);
1708
1711
maybeAddRethrowsNote (Diags, loc, reason);
1709
1712
@@ -1717,6 +1720,10 @@ class Context {
1717
1720
if (!suggestTryFixIt)
1718
1721
return ;
1719
1722
1723
+ // 'try' should go before 'await'
1724
+ if (awaitLoc.isValid ())
1725
+ insertLoc = awaitLoc;
1726
+
1720
1727
Diags.diagnose (loc, diag::note_forgot_try)
1721
1728
.fixItInsert (insertLoc, " try " );
1722
1729
Diags.diagnose (loc, diag::note_error_to_optional)
@@ -2116,14 +2123,16 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2116
2123
DeclContext *OldReasyncDC;
2117
2124
ContextFlags OldFlags;
2118
2125
ConditionalEffectKind OldMaxThrowingKind;
2126
+ SourceLoc OldAwaitLoc;
2119
2127
2120
2128
public:
2121
2129
ContextScope (CheckEffectsCoverage &self, Optional<Context> newContext)
2122
2130
: Self(self), OldContext(self.CurContext),
2123
2131
OldRethrowsDC (self.RethrowsDC),
2124
2132
OldReasyncDC(self.ReasyncDC),
2125
2133
OldFlags(self.Flags),
2126
- OldMaxThrowingKind(self.MaxThrowingKind) {
2134
+ OldMaxThrowingKind(self.MaxThrowingKind),
2135
+ OldAwaitLoc(self.CurContext.awaitLoc) {
2127
2136
if (newContext) self.CurContext = *newContext;
2128
2137
}
2129
2138
@@ -2141,9 +2150,10 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2141
2150
Self.Flags .clear (ContextFlags::HasTryThrowSite);
2142
2151
}
2143
2152
2144
- void enterAwait () {
2153
+ void enterAwait (SourceLoc awaitLoc ) {
2145
2154
Self.Flags .set (ContextFlags::IsAsyncCovered);
2146
2155
Self.Flags .clear (ContextFlags::HasAnyAsyncSite);
2156
+ Self.CurContext .awaitLoc = awaitLoc;
2147
2157
}
2148
2158
2149
2159
void enterAsyncLet () {
@@ -2240,6 +2250,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2240
2250
Self.ReasyncDC = OldReasyncDC;
2241
2251
Self.Flags = OldFlags;
2242
2252
Self.MaxThrowingKind = OldMaxThrowingKind;
2253
+ Self.CurContext .awaitLoc = OldAwaitLoc;
2243
2254
}
2244
2255
};
2245
2256
@@ -2648,12 +2659,13 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2648
2659
break ;
2649
2660
}
2650
2661
}
2662
+
2651
2663
ShouldRecurse_t checkAwait (AwaitExpr *E) {
2652
2664
2653
2665
// Walk the operand.
2654
2666
ContextScope scope (*this , None);
2655
- scope.enterAwait ();
2656
-
2667
+ scope.enterAwait (E-> getAwaitLoc () );
2668
+
2657
2669
E->getSubExpr ()->walk (*this );
2658
2670
2659
2671
// Warn about 'await' expressions that weren't actually needed, unless of
@@ -2666,7 +2678,7 @@ class CheckEffectsCoverage : public EffectsHandlingWalker<CheckEffectsCoverage>
2666
2678
CurContext.diagnoseUnhandledAsyncSite (Ctx.Diags , E, None,
2667
2679
/* forAwait=*/ true );
2668
2680
}
2669
-
2681
+
2670
2682
// Inform the parent of the walk that an 'await' exists here.
2671
2683
scope.preserveCoverageFromAwaitOperand ();
2672
2684
return ShouldNotRecurse;
0 commit comments