@@ -2432,7 +2432,8 @@ bool Parser::
24322432parseClosureSignatureIfPresent (SourceRange &bracketRange,
24332433 SmallVectorImpl<CaptureListEntry> &captureList,
24342434 VarDecl *&capturedSelfDecl,
2435- ParameterList *¶ms, SourceLoc &throwsLoc,
2435+ ParameterList *¶ms,
2436+ SourceLoc &asyncLoc, SourceLoc &throwsLoc,
24362437 SourceLoc &arrowLoc,
24372438 TypeExpr *&explicitResultType, SourceLoc &inLoc){
24382439 // Clear out result parameters.
@@ -2444,6 +2445,24 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24442445 explicitResultType = nullptr ;
24452446 inLoc = SourceLoc ();
24462447
2448+ // Consume 'async', 'throws', and 'rethrows', but in any order.
2449+ auto consumeAsyncThrows = [&] {
2450+ bool hadAsync = false ;
2451+ if (Context.LangOpts .EnableExperimentalConcurrency &&
2452+ Tok.isContextualKeyword (" async" )) {
2453+ consumeToken ();
2454+ hadAsync = true ;
2455+ }
2456+
2457+ if (!consumeIf (tok::kw_throws) && !consumeIf (tok::kw_rethrows))
2458+ return ;
2459+
2460+ if (Context.LangOpts .EnableExperimentalConcurrency && !hadAsync &&
2461+ Tok.isContextualKeyword (" async" )) {
2462+ consumeToken ();
2463+ }
2464+ };
2465+
24472466 // If we have a leading token that may be part of the closure signature, do a
24482467 // speculative parse to validate it and look for 'in'.
24492468 if (Tok.isAny (tok::l_paren, tok::l_square, tok::identifier, tok::kw__)) {
@@ -2465,7 +2484,8 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24652484
24662485 // Consume the ')', if it's there.
24672486 if (consumeIf (tok::r_paren)) {
2468- consumeIf (tok::kw_throws) || consumeIf (tok::kw_rethrows);
2487+ consumeAsyncThrows ();
2488+
24692489 // Parse the func-signature-result, if present.
24702490 if (consumeIf (tok::arrow)) {
24712491 if (!canParseType ())
@@ -2485,8 +2505,8 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
24852505
24862506 return false ;
24872507 }
2488-
2489- consumeIf (tok::kw_throws) || consumeIf (tok::kw_rethrows );
2508+
2509+ consumeAsyncThrows ( );
24902510
24912511 // Parse the func-signature-result, if present.
24922512 if (consumeIf (tok::arrow)) {
@@ -2682,11 +2702,10 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26822702
26832703 params = ParameterList::create (Context, elements);
26842704 }
2685-
2686- if (Tok.is (tok::kw_throws)) {
2687- throwsLoc = consumeToken ();
2688- } else if (Tok.is (tok::kw_rethrows)) {
2689- throwsLoc = consumeToken ();
2705+
2706+ bool rethrows = false ;
2707+ parseAsyncThrows (SourceLoc (), asyncLoc, throwsLoc, &rethrows);
2708+ if (rethrows) {
26902709 diagnose (throwsLoc, diag::rethrowing_function_type)
26912710 .fixItReplace (throwsLoc, " throws" );
26922711 }
@@ -2803,13 +2822,14 @@ ParserResult<Expr> Parser::parseExprClosure() {
28032822 SmallVector<CaptureListEntry, 2 > captureList;
28042823 VarDecl *capturedSelfDecl;
28052824 ParameterList *params = nullptr ;
2825+ SourceLoc asyncLoc;
28062826 SourceLoc throwsLoc;
28072827 SourceLoc arrowLoc;
28082828 TypeExpr *explicitResultType;
28092829 SourceLoc inLoc;
2810- parseClosureSignatureIfPresent (bracketRange, captureList,
2811- capturedSelfDecl, params, throwsLoc,
2812- arrowLoc, explicitResultType, inLoc);
2830+ parseClosureSignatureIfPresent (
2831+ bracketRange, captureList, capturedSelfDecl, params, asyncLoc , throwsLoc,
2832+ arrowLoc, explicitResultType, inLoc);
28132833
28142834 // If the closure was created in the context of an array type signature's
28152835 // size expression, there will not be a local context. A parse error will
@@ -2824,10 +2844,9 @@ ParserResult<Expr> Parser::parseExprClosure() {
28242844 unsigned discriminator = CurLocalContext->claimNextClosureDiscriminator ();
28252845
28262846 // Create the closure expression and enter its context.
2827- auto *closure = new (Context) ClosureExpr (bracketRange, capturedSelfDecl,
2828- params, throwsLoc, arrowLoc, inLoc,
2829- explicitResultType, discriminator,
2830- CurDeclContext);
2847+ auto *closure = new (Context) ClosureExpr (
2848+ bracketRange, capturedSelfDecl, params, asyncLoc, throwsLoc, arrowLoc,
2849+ inLoc, explicitResultType, discriminator, CurDeclContext);
28312850 // The arguments to the func are defined in their own scope.
28322851 Scope S (this , ScopeKind::ClosureParams);
28332852 ParseFunctionBody cc (*this , closure);
0 commit comments