@@ -99,9 +99,34 @@ pub enum PatternLocation {
99
99
impl < ' a > Parser < ' a > {
100
100
/// Parses a pattern.
101
101
///
102
- /// Corresponds to `pat<no_top_alt>` in RFC 2535 and does not admit or-patterns
103
- /// at the top level. Used when parsing the parameters of lambda expressions,
104
- /// functions, function pointers, and `pat` macro fragments.
102
+ /// Corresponds to `Pattern` in RFC 3637 and admits guard patterns at the top level.
103
+ /// Used when parsing patterns in all cases where neither `PatternNoTopGuard` nor
104
+ /// `PatternNoTopAlt` (see below) are used.
105
+ pub fn parse_pat_allow_top_guard (
106
+ & mut self ,
107
+ expected : Option < Expected > ,
108
+ rc : RecoverComma ,
109
+ ra : RecoverColon ,
110
+ rt : CommaRecoveryMode ,
111
+ ) -> PResult < ' a , P < Pat > > {
112
+ let pat = self . parse_pat_no_top_guard ( expected, rc, ra, rt) ?;
113
+
114
+ if self . eat_keyword ( kw:: If ) {
115
+ let cond = self . parse_expr ( ) ?;
116
+ // Feature-gate guard patterns
117
+ self . psess . gated_spans . gate ( sym:: guard_patterns, cond. span ) ;
118
+ let span = pat. span . to ( cond. span ) ;
119
+ Ok ( self . mk_pat ( span, PatKind :: Guard ( pat, cond) ) )
120
+ } else {
121
+ Ok ( pat)
122
+ }
123
+ }
124
+
125
+ /// Parses a pattern.
126
+ ///
127
+ /// Corresponds to `PatternNoTopAlt` in RFC 3637 and does not admit or-patterns
128
+ /// or guard patterns at the top level. Used when parsing the parameters of lambda
129
+ /// expressions, functions, function pointers, and `pat_param` macro fragments.
105
130
pub fn parse_pat_no_top_alt (
106
131
& mut self ,
107
132
expected : Option < Expected > ,
@@ -112,25 +137,26 @@ impl<'a> Parser<'a> {
112
137
113
138
/// Parses a pattern.
114
139
///
115
- /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level.
116
- /// Used for parsing patterns in all cases when `pat<no_top_alt>` is not used.
140
+ /// Corresponds to `PatternNoTopGuard` in RFC 3637 and allows or-patterns, but not
141
+ /// guard patterns, at the top level. Used for parsing patterns in `pat` fragments (until
142
+ /// the next edition) and `let`, `if let`, and `while let` expressions.
117
143
///
118
144
/// Note that after the FCP in <https://github.com/rust-lang/rust/issues/81415>,
119
145
/// a leading vert is allowed in nested or-patterns, too. This allows us to
120
146
/// simplify the grammar somewhat.
121
- pub fn parse_pat_allow_top_alt (
147
+ pub fn parse_pat_no_top_guard (
122
148
& mut self ,
123
149
expected : Option < Expected > ,
124
150
rc : RecoverComma ,
125
151
ra : RecoverColon ,
126
152
rt : CommaRecoveryMode ,
127
153
) -> PResult < ' a , P < Pat > > {
128
- self . parse_pat_allow_top_alt_inner ( expected, rc, ra, rt, None ) . map ( |( pat, _) | pat)
154
+ self . parse_pat_no_top_guard_inner ( expected, rc, ra, rt, None ) . map ( |( pat, _) | pat)
129
155
}
130
156
131
157
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
132
158
/// recovered).
133
- fn parse_pat_allow_top_alt_inner (
159
+ fn parse_pat_no_top_guard_inner (
134
160
& mut self ,
135
161
expected : Option < Expected > ,
136
162
rc : RecoverComma ,
@@ -231,7 +257,7 @@ impl<'a> Parser<'a> {
231
257
// We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
232
258
// or-patterns so that we can detect when a user tries to use it. This allows us to print a
233
259
// better error message.
234
- let ( pat, trailing_vert) = self . parse_pat_allow_top_alt_inner (
260
+ let ( pat, trailing_vert) = self . parse_pat_no_top_guard_inner (
235
261
expected,
236
262
rc,
237
263
RecoverColon :: No ,
@@ -696,7 +722,7 @@ impl<'a> Parser<'a> {
696
722
} else if self . check ( & token:: OpenDelim ( Delimiter :: Bracket ) ) {
697
723
// Parse `[pat, pat,...]` as a slice pattern.
698
724
let ( pats, _) = self . parse_delim_comma_seq ( Delimiter :: Bracket , |p| {
699
- p. parse_pat_allow_top_alt (
725
+ p. parse_pat_allow_top_guard (
700
726
None ,
701
727
RecoverComma :: No ,
702
728
RecoverColon :: No ,
@@ -944,7 +970,7 @@ impl<'a> Parser<'a> {
944
970
let open_paren = self . token . span ;
945
971
946
972
let ( fields, trailing_comma) = self . parse_paren_comma_seq ( |p| {
947
- p. parse_pat_allow_top_alt (
973
+ p. parse_pat_allow_top_guard (
948
974
None ,
949
975
RecoverComma :: No ,
950
976
RecoverColon :: No ,
@@ -1361,7 +1387,7 @@ impl<'a> Parser<'a> {
1361
1387
path : Path ,
1362
1388
) -> PResult < ' a , PatKind > {
1363
1389
let ( fields, _) = self . parse_paren_comma_seq ( |p| {
1364
- p. parse_pat_allow_top_alt (
1390
+ p. parse_pat_allow_top_guard (
1365
1391
None ,
1366
1392
RecoverComma :: No ,
1367
1393
RecoverColon :: No ,
@@ -1396,7 +1422,7 @@ impl<'a> Parser<'a> {
1396
1422
self . parse_builtin ( |self_, _lo, ident| {
1397
1423
Ok ( match ident. name {
1398
1424
// builtin#deref(PAT)
1399
- sym:: deref => Some ( ast:: PatKind :: Deref ( self_. parse_pat_allow_top_alt (
1425
+ sym:: deref => Some ( ast:: PatKind :: Deref ( self_. parse_pat_allow_top_guard (
1400
1426
None ,
1401
1427
RecoverComma :: Yes ,
1402
1428
RecoverColon :: Yes ,
@@ -1671,7 +1697,7 @@ impl<'a> Parser<'a> {
1671
1697
// Parsing a pattern of the form `fieldname: pat`.
1672
1698
let fieldname = self . parse_field_name ( ) ?;
1673
1699
self . bump ( ) ;
1674
- let pat = self . parse_pat_allow_top_alt (
1700
+ let pat = self . parse_pat_allow_top_guard (
1675
1701
None ,
1676
1702
RecoverComma :: No ,
1677
1703
RecoverColon :: No ,
0 commit comments