From bd6c04fe20c8a02ba066668b9e555dda05706d23 Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Fri, 2 May 2025 17:09:13 -0700 Subject: [PATCH] [Parse] Parse operator function with value generics Operator function parsing has a heuristics to determine if `<` a part of the operator name or the generic parameter clause. Handle `let` there because value generics uses it. rdar://149556573 (cherry picked from commit 682d2634baba3bb442c4d1926d3448463e6c5516) --- lib/Parse/ParseDecl.cpp | 8 ++++---- test/Sema/value_generics.swift | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 4b420556499b6..8c821d20b5660 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -8737,12 +8737,12 @@ ParserResult Parser::parseDeclFunc(SourceLoc StaticLoc, SourceLoc NameLoc; if (Tok.isAnyOperator() || Tok.isAny(tok::exclaim_postfix, tok::amp_prefix)) { // If the name is an operator token that ends in '<' and the following token - // is an identifier, split the '<' off as a separate token. This allows - // things like 'func ==(x:T, y:T) {}' to parse as '==' with generic type - // variable '' as expected. + // is an identifier or 'let', split the '<' off as a separate token. This + // allows things like 'func ==(x:T, y:T) {}' to parse as '==' with + // generic type variable '' as expected. auto NameStr = Tok.getText(); if (NameStr.size() > 1 && NameStr.back() == '<' && - peekToken().is(tok::identifier)) { + peekToken().isAny(tok::identifier, tok::kw_let)) { NameStr = NameStr.slice(0, NameStr.size() - 1); } SimpleName = Context.getIdentifier(NameStr); diff --git a/test/Sema/value_generics.swift b/test/Sema/value_generics.swift index 0f5d38b9dce15..e387d04f3f5f7 100644 --- a/test/Sema/value_generics.swift +++ b/test/Sema/value_generics.swift @@ -51,6 +51,8 @@ func c(with a: A) {} // OK func d(with a: A) {} // expected-error {{cannot pass type 'T' as a value for generic value 'N'}} func e(with a: A) {} // expected-error {{cannot pass type 'Int' as a value for generic value 'N'}} +func *(l: A, r: A) -> Int { l.int * r.int } + struct Generic {} struct GenericWithIntParam {}