@@ -1317,6 +1317,42 @@ ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
13171317 return parseMatchingPatternAsBinding (newPatternBindingState, varLoc,
13181318 isExprBasic);
13191319 }
1320+
1321+ // The `borrowing` modifier is a contextual keyword, so it's only accepted
1322+ // directly applied to a binding name, as in `case .foo(borrowing x)`.
1323+ if (Context.LangOpts .hasFeature (Feature::BorrowingSwitch)) {
1324+ if (Tok.isContextualKeyword (" _borrowing" )
1325+ && peekToken ().isAny (tok::identifier, tok::kw_self, tok::dollarident,
1326+ tok::code_complete)
1327+ && !peekToken ().isAtStartOfLine ()) {
1328+ Tok.setKind (tok::contextual_keyword);
1329+ SourceLoc borrowingLoc = consumeToken ();
1330+
1331+ // If we have `case borrowing x.`, `x(`, `x[`, or `x<` then this looks
1332+ // like an attempt to include a subexpression under a `borrowing`
1333+ // binding, which isn't yet supported.
1334+ if (peekToken ().isAny (tok::period, tok::period_prefix, tok::l_paren,
1335+ tok::l_square)
1336+ || (peekToken ().isAnyOperator () && peekToken ().getText ().equals (" <" ))) {
1337+
1338+ // Diagnose the unsupported production.
1339+ diagnose (Tok.getLoc (),
1340+ diag::borrowing_subpattern_unsupported);
1341+
1342+ // Recover by parsing as if it was supported.
1343+ return parseMatchingPattern (isExprBasic);
1344+ }
1345+ Identifier name;
1346+ SourceLoc nameLoc = consumeIdentifier (name,
1347+ /* diagnoseDollarPrefix*/ false );
1348+ auto namedPattern = createBindingFromPattern (nameLoc, name,
1349+ VarDecl::Introducer::Borrowing);
1350+ auto bindPattern = new (Context) BindingPattern (
1351+ borrowingLoc, VarDecl::Introducer::Borrowing, namedPattern);
1352+
1353+ return makeParserResult (bindPattern);
1354+ }
1355+ }
13201356
13211357 // matching-pattern ::= 'is' type
13221358 if (Tok.is (tok::kw_is)) {
@@ -1396,6 +1432,15 @@ Parser::parseMatchingPatternAsBinding(PatternBindingState newState,
13961432}
13971433
13981434bool Parser::isOnlyStartOfMatchingPattern () {
1435+ if (Context.LangOpts .hasFeature (Feature::BorrowingSwitch)) {
1436+ if (Tok.isContextualKeyword (" _borrowing" )
1437+ && peekToken ().isAny (tok::identifier, tok::kw_self, tok::dollarident,
1438+ tok::code_complete)
1439+ && !peekToken ().isAtStartOfLine ()) {
1440+ return true ;
1441+ }
1442+ }
1443+
13991444 return Tok.isAny (tok::kw_var, tok::kw_let, tok::kw_is) ||
14001445 (Context.LangOpts .hasFeature (Feature::ReferenceBindings) &&
14011446 Tok.isAny (tok::kw_inout));
0 commit comments