@@ -126,20 +126,26 @@ ParserResult<Expr> Parser::parseExprAs() {
126126// / 'async'? 'throws'? '->'
127127ParserResult<Expr> Parser::parseExprArrow () {
128128 SourceLoc asyncLoc, throwsLoc, arrowLoc;
129+ ParserStatus status;
129130
130- parseAsyncThrows (SourceLoc (), asyncLoc, throwsLoc, /* rethrows=*/ nullptr );
131+ status |= parseEffectsSpecifiers (SourceLoc (), asyncLoc, throwsLoc,
132+ /* rethrows=*/ nullptr );
133+ if (status.hasCodeCompletion () && !CodeCompletion) {
134+ // Trigger delayed parsing, no need to continue.
135+ return status;
136+ }
131137
132138 if (Tok.isNot (tok::arrow)) {
133139 assert (throwsLoc.isValid () || asyncLoc.isValid ());
134140 diagnose (throwsLoc.isValid () ? throwsLoc : asyncLoc,
135141 diag::async_or_throws_in_wrong_position,
136- throwsLoc.isValid () ? 0 : 2 );
142+ throwsLoc.isValid () ? " throws " : " async " );
137143 return nullptr ;
138144 }
139145
140146 arrowLoc = consumeToken (tok::arrow);
141147
142- parseAsyncThrows (arrowLoc, asyncLoc, throwsLoc, /* rethrows=*/ nullptr );
148+ parseEffectsSpecifiers (arrowLoc, asyncLoc, throwsLoc, /* rethrows=*/ nullptr );
143149
144150 auto arrow = new (Context) ArrowExpr (asyncLoc, throwsLoc, arrowLoc);
145151 return makeParserResult (arrow);
@@ -2317,14 +2323,14 @@ static void printTupleNames(const TypeRepr *typeRepr, llvm::raw_ostream &OS) {
23172323 OS << " )" ;
23182324}
23192325
2320- bool Parser::
2321- parseClosureSignatureIfPresent ( SourceRange &bracketRange,
2322- SmallVectorImpl<CaptureListEntry> &captureList,
2323- VarDecl *&capturedSelfDecl,
2324- ParameterList *¶ms,
2325- SourceLoc &asyncLoc, SourceLoc &throwsLoc,
2326- SourceLoc &arrowLoc,
2327- TypeExpr *&explicitResultType, SourceLoc &inLoc){
2326+ ParserStatus Parser::parseClosureSignatureIfPresent (
2327+ SourceRange &bracketRange,
2328+ SmallVectorImpl<CaptureListEntry> &captureList,
2329+ VarDecl *&capturedSelfDecl,
2330+ ParameterList *¶ms,
2331+ SourceLoc &asyncLoc, SourceLoc &throwsLoc,
2332+ SourceLoc &arrowLoc,
2333+ TypeExpr *&explicitResultType, SourceLoc &inLoc) {
23282334 // Clear out result parameters.
23292335 bracketRange = SourceRange ();
23302336 capturedSelfDecl = nullptr ;
@@ -2335,21 +2341,10 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23352341 inLoc = SourceLoc ();
23362342
23372343 // Consume 'async', 'throws', and 'rethrows', but in any order.
2338- auto consumeAsyncThrows = [&] {
2339- bool hadAsync = false ;
2340- if (shouldParseExperimentalConcurrency () &&
2341- Tok.isContextualKeyword (" async" )) {
2342- consumeToken ();
2343- hadAsync = true ;
2344- }
2345-
2346- if (!consumeIf (tok::kw_throws) && !consumeIf (tok::kw_rethrows))
2347- return ;
2348-
2349- if (shouldParseExperimentalConcurrency () && !hadAsync &&
2350- Tok.isContextualKeyword (" async" )) {
2344+ auto consumeEffectsSpecifiers = [&] {
2345+ while (isEffectsSpecifier (Tok) ||
2346+ (Tok.is (tok::code_complete) && !Tok.isAtStartOfLine ()))
23512347 consumeToken ();
2352- }
23532348 };
23542349
23552350 // If we have a leading token that may be part of the closure signature, do a
@@ -2361,7 +2356,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23612356 if (consumeIf (tok::l_square)) {
23622357 skipUntil (tok::r_square);
23632358 if (!consumeIf (tok::r_square))
2364- return false ;
2359+ return makeParserSuccess () ;
23652360 }
23662361
23672362 // Parse pattern-tuple func-signature-result? 'in'.
@@ -2373,12 +2368,14 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23732368
23742369 // Consume the ')', if it's there.
23752370 if (consumeIf (tok::r_paren)) {
2376- consumeAsyncThrows ();
2371+ consumeEffectsSpecifiers ();
23772372
23782373 // Parse the func-signature-result, if present.
23792374 if (consumeIf (tok::arrow)) {
23802375 if (!canParseType ())
2381- return false ;
2376+ return makeParserSuccess ();
2377+
2378+ consumeEffectsSpecifiers ();
23822379 }
23832380 }
23842381
@@ -2392,27 +2389,30 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
23922389 continue ;
23932390 }
23942391
2395- return false ;
2392+ return makeParserSuccess () ;
23962393 }
23972394
2398- consumeAsyncThrows ();
2395+ consumeEffectsSpecifiers ();
23992396
24002397 // Parse the func-signature-result, if present.
24012398 if (consumeIf (tok::arrow)) {
24022399 if (!canParseType ())
2403- return false ;
2400+ return makeParserSuccess ();
2401+
2402+ consumeEffectsSpecifiers ();
24042403 }
24052404 }
24062405
24072406 // Parse the 'in' at the end.
24082407 if (Tok.isNot (tok::kw_in))
2409- return false ;
2408+ return makeParserSuccess () ;
24102409
24112410 // Okay, we have a closure signature.
24122411 } else {
24132412 // No closure signature.
2414- return false ;
2413+ return makeParserSuccess () ;
24152414 }
2415+ ParserStatus status;
24162416 SyntaxParsingContext ClosureSigCtx (SyntaxContext, SyntaxKind::ClosureSignature);
24172417 if (Tok.is (tok::l_square) && peekToken ().is (tok::r_square)) {
24182418
@@ -2557,7 +2557,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25572557 if (pattern.isNonNull ())
25582558 params = pattern.get ();
25592559 else
2560- invalid = true ;
2560+ status. setIsParseError () ;
25612561 } else {
25622562 SyntaxParsingContext ClParamListCtx (SyntaxContext,
25632563 SyntaxKind::ClosureParamList);
@@ -2568,7 +2568,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25682568 SyntaxParsingContext ClParamCtx (SyntaxContext, SyntaxKind::ClosureParam);
25692569 if (Tok.isNot (tok::identifier, tok::kw__)) {
25702570 diagnose (Tok, diag::expected_closure_parameter_name);
2571- invalid = true ;
2571+ status. setIsParseError () ;
25722572 break ;
25732573 }
25742574
@@ -2592,12 +2592,8 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
25922592 params = ParameterList::create (Context, elements);
25932593 }
25942594
2595- bool rethrows = false ;
2596- parseAsyncThrows (SourceLoc (), asyncLoc, throwsLoc, &rethrows);
2597- if (rethrows) {
2598- diagnose (throwsLoc, diag::rethrowing_function_type)
2599- .fixItReplace (throwsLoc, " throws" );
2600- }
2595+ status |= parseEffectsSpecifiers (SourceLoc (), asyncLoc, throwsLoc,
2596+ /* rethrows*/ nullptr );
26012597
26022598 // Parse the optional explicit return type.
26032599 if (Tok.is (tok::arrow)) {
@@ -2611,9 +2607,13 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26112607 if (!explicitResultTypeRepr) {
26122608 // If we couldn't parse the result type, clear out the arrow location.
26132609 arrowLoc = SourceLoc ();
2614- invalid = true ;
2610+ status. setIsParseError () ;
26152611 } else {
26162612 explicitResultType = new (Context) TypeExpr (explicitResultTypeRepr);
2613+
2614+ // Check for 'throws' and 'rethrows' after the type and correct it.
2615+ parseEffectsSpecifiers (arrowLoc, asyncLoc, throwsLoc,
2616+ /* rethrows*/ nullptr );
26172617 }
26182618 }
26192619 }
@@ -2651,7 +2651,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26512651 }
26522652
26532653 if (!params)
2654- return invalid ;
2654+ return status ;
26552655
26562656 // If this was a closure declaration (maybe even trailing)
26572657 // tuple parameter destructuring is one of the common
@@ -2689,14 +2689,15 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
26892689 .fixItReplace (param->getSourceRange (), argName)
26902690 .fixItInsert (Tok.getLoc (), OS.str ());
26912691
2692- invalid = true ;
2692+ status. setIsParseError () ;
26932693 }
26942694
2695- return invalid ;
2695+ return status ;
26962696}
26972697
26982698ParserResult<Expr> Parser::parseExprClosure () {
26992699 assert (Tok.is (tok::l_brace) && " Not at a left brace?" );
2700+ ParserStatus Status;
27002701 SyntaxParsingContext ClosureContext (SyntaxContext, SyntaxKind::ClosureExpr);
27012702 // We may be parsing this closure expr in a matching pattern context. If so,
27022703 // reset our state to not be in a pattern for any recursive pattern parses.
@@ -2716,7 +2717,7 @@ ParserResult<Expr> Parser::parseExprClosure() {
27162717 SourceLoc arrowLoc;
27172718 TypeExpr *explicitResultType;
27182719 SourceLoc inLoc;
2719- parseClosureSignatureIfPresent (
2720+ Status |= parseClosureSignatureIfPresent (
27202721 bracketRange, captureList, capturedSelfDecl, params, asyncLoc, throwsLoc,
27212722 arrowLoc, explicitResultType, inLoc);
27222723
@@ -2751,7 +2752,6 @@ ParserResult<Expr> Parser::parseExprClosure() {
27512752
27522753 // Parse the body.
27532754 SmallVector<ASTNode, 4 > bodyElements;
2754- ParserStatus Status;
27552755 Status |= parseBraceItems (bodyElements, BraceItemListKind::Brace);
27562756
27572757 if (SourceMgr.rangeContainsCodeCompletionLoc ({leftBrace, PreviousLoc})) {
0 commit comments