Skip to content

Commit 5d4db0e

Browse files
committed
parse guard patterns and use correct pattern parsers throughout rustc
1 parent 5da66cd commit 5d4db0e

File tree

14 files changed

+47
-40
lines changed

14 files changed

+47
-40
lines changed

compiler/rustc_expand/src/expand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ pub fn parse_ast_fragment<'a>(
989989
}
990990
}
991991
AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?),
992-
AstFragmentKind::Pat => AstFragment::Pat(this.parse_pat_no_top_guard(
992+
AstFragmentKind::Pat => AstFragment::Pat(this.parse_pat_allow_top_guard(
993993
None,
994994
RecoverComma::No,
995995
RecoverColon::Yes,

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2767,7 +2767,7 @@ impl<'a> Parser<'a> {
27672767
};
27682768
// Try to parse the pattern `for ($PAT) in $EXPR`.
27692769
let pat = match (
2770-
self.parse_pat_no_top_guard(
2770+
self.parse_pat_allow_top_guard(
27712771
None,
27722772
RecoverComma::Yes,
27732773
RecoverColon::Yes,

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,19 @@ impl<'a> Parser<'a> {
101101
/// `PatternNoTopAlt` (see below) are used.
102102
pub fn parse_pat_allow_top_guard(
103103
&mut self,
104-
_expected: Option<Expected>,
105-
_rc: RecoverComma,
106-
_ra: RecoverColon,
107-
_rt: CommaRecoveryMode,
104+
expected: Option<Expected>,
105+
rc: RecoverComma,
106+
ra: RecoverColon,
107+
rt: CommaRecoveryMode,
108108
) -> PResult<'a, P<Pat>> {
109-
todo!()
109+
let pat = self.parse_pat_no_top_guard(expected, rc, ra, rt)?;
110+
111+
if self.eat_keyword(kw::If) {
112+
let cond = self.parse_expr()?;
113+
Ok(self.mk_pat(pat.span.to(cond.span), PatKind::Guard(pat, cond)))
114+
} else {
115+
Ok(pat)
116+
}
110117
}
111118

112119
/// Parses a pattern.
@@ -125,8 +132,8 @@ impl<'a> Parser<'a> {
125132
/// Parses a pattern.
126133
///
127134
/// Corresponds to `PatternNoTopGuard` in RFC 3637 and allows or-patterns, but not
128-
/// guard patterns, at the top level. Used for parsing patterns in `pat` fragments and
129-
/// `let`, `if let`, and `while let` expressions.
135+
/// guard patterns, at the top level. Used for parsing patterns in `pat` fragments (until
136+
/// the next edition) and `let`, `if let`, and `while let` expressions.
130137
///
131138
/// Note that after the FCP in <https://github.com/rust-lang/rust/issues/81415>,
132139
/// a leading vert is allowed in nested or-patterns, too. This allows us to
@@ -709,7 +716,7 @@ impl<'a> Parser<'a> {
709716
} else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
710717
// Parse `[pat, pat,...]` as a slice pattern.
711718
let (pats, _) = self.parse_delim_comma_seq(Delimiter::Bracket, |p| {
712-
p.parse_pat_no_top_guard(
719+
p.parse_pat_allow_top_guard(
713720
None,
714721
RecoverComma::No,
715722
RecoverColon::No,
@@ -957,7 +964,7 @@ impl<'a> Parser<'a> {
957964
let open_paren = self.token.span;
958965

959966
let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
960-
p.parse_pat_no_top_guard(
967+
p.parse_pat_allow_top_guard(
961968
None,
962969
RecoverComma::No,
963970
RecoverColon::No,
@@ -1372,7 +1379,7 @@ impl<'a> Parser<'a> {
13721379
path: Path,
13731380
) -> PResult<'a, PatKind> {
13741381
let (fields, _) = self.parse_paren_comma_seq(|p| {
1375-
p.parse_pat_no_top_guard(
1382+
p.parse_pat_allow_top_guard(
13761383
None,
13771384
RecoverComma::No,
13781385
RecoverColon::No,
@@ -1407,7 +1414,7 @@ impl<'a> Parser<'a> {
14071414
self.parse_builtin(|self_, _lo, ident| {
14081415
Ok(match ident.name {
14091416
// builtin#deref(PAT)
1410-
sym::deref => Some(ast::PatKind::Deref(self_.parse_pat_no_top_guard(
1417+
sym::deref => Some(ast::PatKind::Deref(self_.parse_pat_allow_top_guard(
14111418
None,
14121419
RecoverComma::Yes,
14131420
RecoverColon::Yes,
@@ -1655,7 +1662,7 @@ impl<'a> Parser<'a> {
16551662
// Parsing a pattern of the form `fieldname: pat`.
16561663
let fieldname = self.parse_field_name()?;
16571664
self.bump();
1658-
let pat = self.parse_pat_no_top_guard(
1665+
let pat = self.parse_pat_allow_top_guard(
16591666
None,
16601667
RecoverComma::No,
16611668
RecoverColon::No,

compiler/rustc_parse/src/parser/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl<'a> Parser<'a> {
469469
PathStyle::Pat
470470
if let Ok(_) = self
471471
.parse_paren_comma_seq(|p| {
472-
p.parse_pat_no_top_guard(
472+
p.parse_pat_allow_top_guard(
473473
None,
474474
RecoverComma::No,
475475
RecoverColon::No,

tests/ui/parser/issues/issue-72373.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fn foo(c: &[u32], n: u32) -> u32 {
33
[h, ..] if h > n => 0,
44
[h, ..] if h == n => 1,
55
[h, ref ts..] => foo(c, n - h) + foo(ts, n),
6-
//~^ ERROR expected one of `,`, `@`, `]`, or `|`, found `..`
6+
//~^ ERROR expected one of `,`, `@`, `]`, `if`, or `|`, found `..`
77
[] => 0,
88
}
99
}

tests/ui/parser/issues/issue-72373.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected one of `,`, `@`, `]`, or `|`, found `..`
1+
error: expected one of `,`, `@`, `]`, `if`, or `|`, found `..`
22
--> $DIR/issue-72373.rs:5:19
33
|
44
LL | [h, ref ts..] => foo(c, n - h) + foo(ts, n),
5-
| ^^ expected one of `,`, `@`, `]`, or `|`
5+
| ^^ expected one of `,`, `@`, `]`, `if`, or `|`
66
|
77
help: if you meant to bind the contents of the rest of the array pattern into `ts`, use `@`
88
|

tests/ui/parser/misspelled-keywords/ref.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: expected one of `)`, `,`, `@`, or `|`, found `list`
1+
error: expected one of `)`, `,`, `@`, `if`, or `|`, found `list`
22
--> $DIR/ref.rs:4:19
33
|
44
LL | Some(refe list) => println!("{list:?}"),
5-
| ^^^^ expected one of `)`, `,`, `@`, or `|`
5+
| ^^^^ expected one of `)`, `,`, `@`, `if`, or `|`
66
|
77
help: there is a keyword `ref` with a similar name
88
|

tests/ui/parser/pat-lt-bracket-7.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ fn main() {
33
let foo = core::iter::empty();
44

55
for Thing(x[]) in foo {}
6-
//~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
6+
//~^ ERROR: expected one of `)`, `,`, `@`, `if`, or `|`, found `[`
77
}
88

99
const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types

tests/ui/parser/pat-lt-bracket-7.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: expected one of `)`, `,`, `@`, or `|`, found `[`
1+
error: expected one of `)`, `,`, `@`, `if`, or `|`, found `[`
22
--> $DIR/pat-lt-bracket-7.rs:5:16
33
|
44
LL | for Thing(x[]) in foo {}
55
| ^
66
| |
7-
| expected one of `)`, `,`, `@`, or `|`
7+
| expected one of `)`, `,`, `@`, `if`, or `|`
88
| help: missing `,`
99

1010
error[E0308]: mismatched types

tests/ui/parser/recover/recover-pat-exprs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn array_indexing() {
2727
{ let x[0, 1, 2]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
2828
{ let x[0; 20]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
2929
{ let x[]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
30-
{ let (x[]); } //~ error: expected one of `)`, `,`, `@`, or `|`, found `[`
30+
{ let (x[]); } //~ error: expected one of `)`, `,`, `@`, `if`, or `|`, found `[`
3131
//~^ missing `,`
3232
}
3333

@@ -95,12 +95,12 @@ fn main() {
9595
f?() => (),
9696
//~^ error: expected a pattern, found an expression
9797
(_ + 1) => (),
98-
//~^ error: expected one of `)`, `,`, or `|`, found `+`
98+
//~^ error: expected one of `)`, `,`, `if`, or `|`, found `+`
9999
}
100100

101101
let 1 + 1 = 2;
102102
//~^ error: expected a pattern, found an expression
103103

104104
let b = matches!(x, (x * x | x.f()) | x[0]);
105-
//~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
105+
//~^ error: expected one of `)`, `,`, `@`, `if`, or `|`, found `*`
106106
}

0 commit comments

Comments
 (0)