@@ -2460,7 +2460,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
24602460 // speculative parse to validate it and look for 'in'.
24612461 if (Tok.isAny (
24622462 tok::at_sign, tok::l_paren, tok::l_square, tok::identifier,
2463- tok::kw__)) {
2463+ tok::kw__, tok::code_complete )) {
24642464 BacktrackingScope backtrack (*this );
24652465
24662466 // Consume attributes.
@@ -2496,11 +2496,11 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
24962496 }
24972497
24982498 // Okay, we have a closure signature.
2499- } else if (Tok.isIdentifierOrUnderscore ()) {
2499+ } else if (Tok.isIdentifierOrUnderscore () || Tok. is (tok::code_complete) ) {
25002500 // Parse identifier (',' identifier)*
25012501 consumeToken ();
25022502 while (consumeIf (tok::comma)) {
2503- if (Tok.isIdentifierOrUnderscore ()) {
2503+ if (Tok.isIdentifierOrUnderscore () || Tok. is (tok::code_complete) ) {
25042504 consumeToken ();
25052505 continue ;
25062506 }
@@ -2575,7 +2575,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
25752575 if (!consumeIf (tok::r_paren, ownershipLocEnd))
25762576 diagnose (Tok, diag::attr_unowned_expected_rparen);
25772577 }
2578- } else if (Tok.isAny (tok::identifier, tok::kw_self) &&
2578+ } else if (Tok.isAny (tok::identifier, tok::kw_self, tok::code_complete ) &&
25792579 peekToken ().isAny (tok::equal, tok::comma, tok::r_square)) {
25802580 // "x = 42", "x," and "x]" are all strong captures of x.
25812581 } else {
@@ -2584,7 +2584,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
25842584 continue ;
25852585 }
25862586
2587- if (Tok.isNot (tok::identifier, tok::kw_self)) {
2587+ if (Tok.isNot (tok::identifier, tok::kw_self, tok::code_complete )) {
25882588 diagnose (Tok, diag::expected_capture_specifier_name);
25892589 skipUntil (tok::comma, tok::r_square);
25902590 continue ;
@@ -2602,10 +2602,20 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26022602 if (peekToken ().isNot (tok::equal)) {
26032603 // If this is the simple case, then the identifier is both the name and
26042604 // the expression to capture.
2605- name = Context.getIdentifier (Tok.getText ());
2606- auto initializerResult = parseExprIdentifier ();
2607- status |= initializerResult;
2608- initializer = initializerResult.get ();
2605+ if (!Tok.is (tok::code_complete)) {
2606+ name = Context.getIdentifier (Tok.getText ());
2607+ auto initializerResult = parseExprIdentifier ();
2608+ status |= initializerResult;
2609+ initializer = initializerResult.get ();
2610+ } else {
2611+ auto CCE = new (Context) CodeCompletionExpr (Tok.getLoc ());
2612+ if (CodeCompletion)
2613+ CodeCompletion->completePostfixExprBeginning (CCE);
2614+ name = Identifier ();
2615+ initializer = CCE;
2616+ consumeToken ();
2617+ status.setHasCodeCompletion ();
2618+ }
26092619
26102620 // It is a common error to try to capture a nested field instead of just
26112621 // a local name, reject it with a specific error message.
@@ -2617,7 +2627,13 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26172627
26182628 } else {
26192629 // Otherwise, the name is a new declaration.
2620- consumeIdentifier (name, /* diagnoseDollarPrefix=*/ true );
2630+ if (!Tok.is (tok::code_complete)) {
2631+ consumeIdentifier (name, /* diagnoseDollarPrefix=*/ true );
2632+ } else {
2633+ // Ignore completion token because it's a new declaration.
2634+ name = Identifier ();
2635+ consumeToken (tok::code_complete);
2636+ }
26212637 equalLoc = consumeToken (tok::equal);
26222638
26232639 auto ExprResult = parseExpr (diag::expected_init_capture_specifier);
@@ -2687,7 +2703,7 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26872703 bool HasNext;
26882704 do {
26892705 SyntaxParsingContext ClParamCtx (SyntaxContext, SyntaxKind::ClosureParam);
2690- if (Tok.isNot (tok::identifier, tok::kw__)) {
2706+ if (Tok.isNot (tok::identifier, tok::kw__, tok::code_complete )) {
26912707 diagnose (Tok, diag::expected_closure_parameter_name);
26922708 status.setIsParseError ();
26932709 break ;
@@ -2698,7 +2714,10 @@ ParserStatus Parser::parseClosureSignatureIfPresent(
26982714 if (Tok.is (tok::identifier)) {
26992715 nameLoc = consumeIdentifier (name, /* diagnoseDollarPrefix=*/ false );
27002716 } else {
2701- nameLoc = consumeToken (tok::kw__);
2717+ assert (Tok.isAny (tok::kw__ , tok::code_complete));
2718+ // Consume and ignore code_completion token so that completion don't
2719+ // suggest anything for the parameter name declaration.
2720+ nameLoc = consumeToken ();
27022721 }
27032722 auto var = new (Context)
27042723 ParamDecl (SourceLoc (), SourceLoc (),
0 commit comments