@@ -1664,19 +1664,35 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
16641664 }
16651665
16661666 case tok::identifier: // foo
1667- case tok::kw_self: // self
1668-
1667+ case tok::kw_self: { // self
1668+ auto canParseBindingInPattern = [&]() {
1669+ if (InBindingPattern != PatternBindingState::ImplicitlyImmutable &&
1670+ !InBindingPattern.getIntroducer ().hasValue ()) {
1671+ return false ;
1672+ }
1673+ // If we have "case let x.", "case let x(", or "case let x[", we parse 'x'
1674+ // as a normal name, not a binding, because it is the start of an enum
1675+ // pattern, call, or subscript.
1676+ if (peekToken ().isAny (tok::period, tok::period_prefix, tok::l_paren,
1677+ tok::l_square)) {
1678+ return false ;
1679+ }
1680+ // If we have a generic argument list, this is something like
1681+ // "case let E<Int>.e(y)", and 'E' should be parsed as a normal name, not
1682+ // a binding.
1683+ if (peekToken ().isAnyOperator () && peekToken ().getText ().equals (" <" )) {
1684+ BacktrackingScope S (*this );
1685+ consumeToken ();
1686+ return !canParseAsGenericArgumentList ();
1687+ }
1688+ return true ;
1689+ }();
16691690 // If we are parsing a refutable pattern and are inside a let/var pattern,
16701691 // the identifiers change to be value bindings instead of decl references.
16711692 // Parse and return this as an UnresolvedPatternExpr around a binding. This
16721693 // will be resolved (or rejected) by sema when the overall refutable pattern
16731694 // it transformed from an expression into a pattern.
1674- if ((InBindingPattern == PatternBindingState::ImplicitlyImmutable ||
1675- InBindingPattern.getIntroducer ().hasValue ()) &&
1676- // If we have "case let x." or "case let x(", we parse x as a normal
1677- // name, not a binding, because it is the start of an enum pattern or
1678- // call pattern.
1679- peekToken ().isNot (tok::period, tok::period_prefix, tok::l_paren)) {
1695+ if (canParseBindingInPattern) {
16801696 Identifier name;
16811697 SourceLoc loc = consumeIdentifier (name, /* diagnoseDollarPrefix=*/ false );
16821698 // If we have an inout/let/var, set that as our introducer. otherwise
@@ -1710,6 +1726,7 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
17101726 }
17111727
17121728 LLVM_FALLTHROUGH;
1729+ }
17131730 case tok::kw_Self: // Self
17141731 return parseExprIdentifier ();
17151732
0 commit comments