@@ -4807,33 +4807,22 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
4807
4807
4808
4808
SourceLoc FuncLoc = consumeToken (tok::kw_func);
4809
4809
4810
- // Forgive the lexer
4811
- if (Tok.is (tok::amp_prefix)) {
4812
- Tok.setKind (tok::oper_prefix);
4813
- }
4810
+ // Parse function name.
4814
4811
Identifier SimpleName;
4815
- Token NameTok = Tok;
4816
4812
SourceLoc NameLoc;
4817
-
4818
- if (Tok.isAny (tok::identifier, tok::integer_literal, tok::floating_literal,
4819
- tok::unknown) ||
4820
- Tok.isKeyword ()) {
4821
- // This non-operator path is quite accepting of what tokens might be a name,
4822
- // because we're aggressive about recovering/providing good diagnostics for
4823
- // beginners.
4824
- ParserStatus NameStatus =
4825
- parseIdentifierDeclName (*this , SimpleName, NameLoc, " function" ,
4826
- tok::l_paren, tok::arrow, tok::l_brace,
4827
- TokenProperty::StartsWithLess);
4828
- if (NameStatus.isError ())
4829
- return nullptr ;
4830
- } else {
4831
- // May be operator.
4832
- if (parseAnyIdentifier (SimpleName, NameLoc,
4833
- diag::expected_identifier_in_decl, " function" )) {
4834
- return nullptr ;
4835
- }
4836
- assert (SimpleName.isOperator ());
4813
+ if (Tok.isAnyOperator () || Tok.isAny (tok::exclaim_postfix, tok::amp_prefix)) {
4814
+ // If the name is an operator token that ends in '<' and the following token
4815
+ // is an identifier, split the '<' off as a separate token. This allows
4816
+ // things like 'func ==<T>(x:T, y:T) {}' to parse as '==' with generic type
4817
+ // variable '<T>' as expected.
4818
+ auto NameStr = Tok.getText ();
4819
+ if (NameStr.size () > 1 && NameStr.back () == ' <' &&
4820
+ peekToken ().is (tok::identifier)) {
4821
+ NameStr = NameStr.slice (0 , NameStr.size () - 1 );
4822
+ }
4823
+ SimpleName = Context.getIdentifier (NameStr);
4824
+ NameLoc = consumeStartingCharacterOfCurrentToken (tok::oper_binary_spaced,
4825
+ NameStr.size ());
4837
4826
// Within a protocol, recover from a missing 'static'.
4838
4827
if (Flags & PD_InProtocol) {
4839
4828
switch (StaticSpelling) {
@@ -4855,6 +4844,15 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
4855
4844
llvm_unreachable (" should have been fixed above" );
4856
4845
}
4857
4846
}
4847
+ } else {
4848
+ // This non-operator path is quite accepting of what tokens might be a name,
4849
+ // because we're aggressive about recovering/providing good diagnostics for
4850
+ // beginners.
4851
+ auto NameStatus = parseIdentifierDeclName (
4852
+ *this , SimpleName, NameLoc, " function" , tok::l_paren, tok::arrow,
4853
+ tok::l_brace, TokenProperty::StartsWithLess);
4854
+ if (NameStatus.isError ())
4855
+ return nullptr ;
4858
4856
}
4859
4857
4860
4858
DebuggerContextChange DCC (*this , SimpleName, DeclKind::Func);
@@ -4864,30 +4862,9 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
4864
4862
GenericsScope.emplace (this , ScopeKind::Generics);
4865
4863
GenericParamList *GenericParams;
4866
4864
bool SignatureHasCodeCompletion = false ;
4867
- // If the name is an operator token that ends in '<' and the following token
4868
- // is an identifier, split the '<' off as a separate token. This allows things
4869
- // like 'func ==<T>(x:T, y:T) {}' to parse as '==' with generic type variable
4870
- // '<T>' as expected.
4871
- if (SimpleName.str ().size () > 1 && SimpleName.str ().back () == ' <'
4872
- && Tok.is (tok::identifier)) {
4873
- SimpleName = Context.getIdentifier (SimpleName.str ().
4874
- slice (0 , SimpleName.str ().size () - 1 ));
4875
- SourceLoc LAngleLoc = NameLoc.getAdvancedLoc (SimpleName.str ().size ());
4876
- auto Result = parseGenericParameters (LAngleLoc);
4877
- GenericParams = Result.getPtrOrNull ();
4878
- SignatureHasCodeCompletion |= Result.hasCodeCompletion ();
4879
-
4880
- auto NameTokText = NameTok.getRawText ();
4881
- markSplitToken (tok::identifier,
4882
- NameTokText.substr (0 , NameTokText.size () - 1 ));
4883
- markSplitToken (tok::oper_binary_unspaced,
4884
- NameTokText.substr (NameTokText.size () - 1 ));
4885
-
4886
- } else {
4887
- auto Result = maybeParseGenericParams ();
4888
- GenericParams = Result.getPtrOrNull ();
4889
- SignatureHasCodeCompletion |= Result.hasCodeCompletion ();
4890
- }
4865
+ auto GenericParamResult = maybeParseGenericParams ();
4866
+ GenericParams = GenericParamResult.getPtrOrNull ();
4867
+ SignatureHasCodeCompletion |= GenericParamResult.hasCodeCompletion ();
4891
4868
if (SignatureHasCodeCompletion && !CodeCompletion)
4892
4869
return makeParserCodeCompletionStatus ();
4893
4870
0 commit comments