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