@@ -1664,19 +1664,35 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
1664
1664
}
1665
1665
1666
1666
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
+ }();
1669
1690
// If we are parsing a refutable pattern and are inside a let/var pattern,
1670
1691
// the identifiers change to be value bindings instead of decl references.
1671
1692
// Parse and return this as an UnresolvedPatternExpr around a binding. This
1672
1693
// will be resolved (or rejected) by sema when the overall refutable pattern
1673
1694
// 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) {
1680
1696
Identifier name;
1681
1697
SourceLoc loc = consumeIdentifier (name, /* diagnoseDollarPrefix=*/ false );
1682
1698
// 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) {
1710
1726
}
1711
1727
1712
1728
LLVM_FALLTHROUGH;
1729
+ }
1713
1730
case tok::kw_Self: // Self
1714
1731
return parseExprIdentifier ();
1715
1732
0 commit comments