@@ -126,20 +126,26 @@ ParserResult<Expr> Parser::parseExprAs() {
126
126
// / 'async'? 'throws'? '->'
127
127
ParserResult<Expr> Parser::parseExprArrow () {
128
128
SourceLoc asyncLoc, throwsLoc, arrowLoc;
129
+ ParserStatus status;
129
130
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
+ }
131
137
132
138
if (Tok.isNot (tok::arrow)) {
133
139
assert (throwsLoc.isValid () || asyncLoc.isValid ());
134
140
diagnose (throwsLoc.isValid () ? throwsLoc : asyncLoc,
135
141
diag::async_or_throws_in_wrong_position,
136
- throwsLoc.isValid () ? 0 : 2 );
142
+ throwsLoc.isValid () ? " throws " : " async " );
137
143
return nullptr ;
138
144
}
139
145
140
146
arrowLoc = consumeToken (tok::arrow);
141
147
142
- parseAsyncThrows (arrowLoc, asyncLoc, throwsLoc, /* rethrows=*/ nullptr );
148
+ parseEffectsSpecifiers (arrowLoc, asyncLoc, throwsLoc, /* rethrows=*/ nullptr );
143
149
144
150
auto arrow = new (Context) ArrowExpr (asyncLoc, throwsLoc, arrowLoc);
145
151
return makeParserResult (arrow);
@@ -2317,14 +2323,14 @@ static void printTupleNames(const TypeRepr *typeRepr, llvm::raw_ostream &OS) {
2317
2323
OS << " )" ;
2318
2324
}
2319
2325
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) {
2328
2334
// Clear out result parameters.
2329
2335
bracketRange = SourceRange ();
2330
2336
capturedSelfDecl = nullptr ;
@@ -2335,21 +2341,10 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2335
2341
inLoc = SourceLoc ();
2336
2342
2337
2343
// 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 ()))
2351
2347
consumeToken ();
2352
- }
2353
2348
};
2354
2349
2355
2350
// If we have a leading token that may be part of the closure signature, do a
@@ -2361,7 +2356,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2361
2356
if (consumeIf (tok::l_square)) {
2362
2357
skipUntil (tok::r_square);
2363
2358
if (!consumeIf (tok::r_square))
2364
- return false ;
2359
+ return makeParserSuccess () ;
2365
2360
}
2366
2361
2367
2362
// Parse pattern-tuple func-signature-result? 'in'.
@@ -2373,12 +2368,14 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2373
2368
2374
2369
// Consume the ')', if it's there.
2375
2370
if (consumeIf (tok::r_paren)) {
2376
- consumeAsyncThrows ();
2371
+ consumeEffectsSpecifiers ();
2377
2372
2378
2373
// Parse the func-signature-result, if present.
2379
2374
if (consumeIf (tok::arrow)) {
2380
2375
if (!canParseType ())
2381
- return false ;
2376
+ return makeParserSuccess ();
2377
+
2378
+ consumeEffectsSpecifiers ();
2382
2379
}
2383
2380
}
2384
2381
@@ -2392,27 +2389,30 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2392
2389
continue ;
2393
2390
}
2394
2391
2395
- return false ;
2392
+ return makeParserSuccess () ;
2396
2393
}
2397
2394
2398
- consumeAsyncThrows ();
2395
+ consumeEffectsSpecifiers ();
2399
2396
2400
2397
// Parse the func-signature-result, if present.
2401
2398
if (consumeIf (tok::arrow)) {
2402
2399
if (!canParseType ())
2403
- return false ;
2400
+ return makeParserSuccess ();
2401
+
2402
+ consumeEffectsSpecifiers ();
2404
2403
}
2405
2404
}
2406
2405
2407
2406
// Parse the 'in' at the end.
2408
2407
if (Tok.isNot (tok::kw_in))
2409
- return false ;
2408
+ return makeParserSuccess () ;
2410
2409
2411
2410
// Okay, we have a closure signature.
2412
2411
} else {
2413
2412
// No closure signature.
2414
- return false ;
2413
+ return makeParserSuccess () ;
2415
2414
}
2415
+ ParserStatus status;
2416
2416
SyntaxParsingContext ClosureSigCtx (SyntaxContext, SyntaxKind::ClosureSignature);
2417
2417
if (Tok.is (tok::l_square) && peekToken ().is (tok::r_square)) {
2418
2418
@@ -2557,7 +2557,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2557
2557
if (pattern.isNonNull ())
2558
2558
params = pattern.get ();
2559
2559
else
2560
- invalid = true ;
2560
+ status. setIsParseError () ;
2561
2561
} else {
2562
2562
SyntaxParsingContext ClParamListCtx (SyntaxContext,
2563
2563
SyntaxKind::ClosureParamList);
@@ -2568,7 +2568,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2568
2568
SyntaxParsingContext ClParamCtx (SyntaxContext, SyntaxKind::ClosureParam);
2569
2569
if (Tok.isNot (tok::identifier, tok::kw__)) {
2570
2570
diagnose (Tok, diag::expected_closure_parameter_name);
2571
- invalid = true ;
2571
+ status. setIsParseError () ;
2572
2572
break ;
2573
2573
}
2574
2574
@@ -2592,12 +2592,8 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2592
2592
params = ParameterList::create (Context, elements);
2593
2593
}
2594
2594
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 );
2601
2597
2602
2598
// Parse the optional explicit return type.
2603
2599
if (Tok.is (tok::arrow)) {
@@ -2611,9 +2607,13 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2611
2607
if (!explicitResultTypeRepr) {
2612
2608
// If we couldn't parse the result type, clear out the arrow location.
2613
2609
arrowLoc = SourceLoc ();
2614
- invalid = true ;
2610
+ status. setIsParseError () ;
2615
2611
} else {
2616
2612
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 );
2617
2617
}
2618
2618
}
2619
2619
}
@@ -2651,7 +2651,7 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2651
2651
}
2652
2652
2653
2653
if (!params)
2654
- return invalid ;
2654
+ return status ;
2655
2655
2656
2656
// If this was a closure declaration (maybe even trailing)
2657
2657
// tuple parameter destructuring is one of the common
@@ -2689,14 +2689,15 @@ parseClosureSignatureIfPresent(SourceRange &bracketRange,
2689
2689
.fixItReplace (param->getSourceRange (), argName)
2690
2690
.fixItInsert (Tok.getLoc (), OS.str ());
2691
2691
2692
- invalid = true ;
2692
+ status. setIsParseError () ;
2693
2693
}
2694
2694
2695
- return invalid ;
2695
+ return status ;
2696
2696
}
2697
2697
2698
2698
ParserResult<Expr> Parser::parseExprClosure () {
2699
2699
assert (Tok.is (tok::l_brace) && " Not at a left brace?" );
2700
+ ParserStatus Status;
2700
2701
SyntaxParsingContext ClosureContext (SyntaxContext, SyntaxKind::ClosureExpr);
2701
2702
// We may be parsing this closure expr in a matching pattern context. If so,
2702
2703
// reset our state to not be in a pattern for any recursive pattern parses.
@@ -2716,7 +2717,7 @@ ParserResult<Expr> Parser::parseExprClosure() {
2716
2717
SourceLoc arrowLoc;
2717
2718
TypeExpr *explicitResultType;
2718
2719
SourceLoc inLoc;
2719
- parseClosureSignatureIfPresent (
2720
+ Status |= parseClosureSignatureIfPresent (
2720
2721
bracketRange, captureList, capturedSelfDecl, params, asyncLoc, throwsLoc,
2721
2722
arrowLoc, explicitResultType, inLoc);
2722
2723
@@ -2751,7 +2752,6 @@ ParserResult<Expr> Parser::parseExprClosure() {
2751
2752
2752
2753
// Parse the body.
2753
2754
SmallVector<ASTNode, 4 > bodyElements;
2754
- ParserStatus Status;
2755
2755
Status |= parseBraceItems (bodyElements, BraceItemListKind::Brace);
2756
2756
2757
2757
if (SourceMgr.rangeContainsCodeCompletionLoc ({leftBrace, PreviousLoc})) {
0 commit comments