Skip to content

Commit c28f538

Browse files
committed
Auto merge of rust-lang#14580 - lowr:patch/parse-more-unstable-pat, r=Veykril
Parse more exclusive range patterns and inline const patterns Closes rust-lang#13955 This PR - implements exclusive range pattern without start bound (tracking issue: rust-lang#37854) - additionally moves rest pattern handling into the same place since they only differ in whether another pattern follows; this actually solves some FIXMEs - updates `PATTERN_FIRST` token set to include `const` token so we can parse inline const pattern in nested patterns
2 parents b218009 + 83a93f4 commit c28f538

File tree

7 files changed

+253
-38
lines changed

7 files changed

+253
-38
lines changed

crates/hir-def/src/macro_expansion_tests/mbe/matching.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ stringify!(;
106106

107107
#[test]
108108
fn range_patterns() {
109-
// FIXME: rustc thinks there are three patterns here, not one.
110109
check(
111110
r#"
112111
macro_rules! m {
@@ -118,7 +117,7 @@ m!(.. .. ..);
118117
macro_rules! m {
119118
($($p:pat)*) => (stringify!($($p |)*);)
120119
}
121-
stringify!(.. .. .. |);
120+
stringify!(.. | .. | .. |);
122121
"#]],
123122
);
124123
}

crates/parser/src/grammar/patterns.rs

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub(super) const PATTERN_FIRST: TokenSet =
55
T![box],
66
T![ref],
77
T![mut],
8+
T![const],
89
T!['('],
910
T!['['],
1011
T![&],
@@ -15,6 +16,10 @@ pub(super) const PATTERN_FIRST: TokenSet =
1516

1617
const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]]));
1718

19+
/// Set of possible tokens at the start of a range pattern's end bound.
20+
const RANGE_PAT_END_FIRST: TokenSet =
21+
expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-], T![const]]));
22+
1823
pub(crate) fn pattern(p: &mut Parser<'_>) {
1924
pattern_r(p, PAT_RECOVERY_SET);
2025
}
@@ -105,6 +110,52 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
105110
return;
106111
}
107112

113+
// test exclusive_range_pat
114+
// fn main() {
115+
// match 42 {
116+
// ..0 => {}
117+
// 1..2 => {}
118+
// }
119+
// }
120+
121+
// test dot_dot_pat
122+
// fn main() {
123+
// let .. = ();
124+
// //
125+
// // Tuples
126+
// //
127+
// let (a, ..) = ();
128+
// let (a, ..,) = ();
129+
// let Tuple(a, ..) = ();
130+
// let Tuple(a, ..,) = ();
131+
// let (.., ..) = ();
132+
// let Tuple(.., ..) = ();
133+
// let (.., a, ..) = ();
134+
// let Tuple(.., a, ..) = ();
135+
// //
136+
// // Slices
137+
// //
138+
// let [..] = ();
139+
// let [head, ..] = ();
140+
// let [head, tail @ ..] = ();
141+
// let [head, .., cons] = ();
142+
// let [head, mid @ .., cons] = ();
143+
// let [head, .., .., cons] = ();
144+
// let [head, .., mid, tail @ ..] = ();
145+
// let [head, .., mid, .., cons] = ();
146+
// }
147+
if p.at(T![..]) {
148+
let m = p.start();
149+
p.bump(T![..]);
150+
if p.at_ts(RANGE_PAT_END_FIRST) {
151+
atom_pat(p, recovery_set);
152+
m.complete(p, RANGE_PAT);
153+
} else {
154+
m.complete(p, REST_PAT);
155+
}
156+
return;
157+
}
158+
108159
if let Some(lhs) = atom_pat(p, recovery_set) {
109160
for range_op in [T![...], T![..=], T![..]] {
110161
if p.at(range_op) {
@@ -173,7 +224,6 @@ fn atom_pat(p: &mut Parser<'_>, recovery_set: TokenSet) -> Option<CompletedMarke
173224
_ if paths::is_path_start(p) => path_or_macro_pat(p),
174225
_ if is_literal_pat_start(p) => literal_pat(p),
175226

176-
T![.] if p.at(T![..]) => rest_pat(p),
177227
T![_] => wildcard_pat(p),
178228
T![&] => ref_pat(p),
179229
T!['('] => tuple_pat(p),
@@ -334,39 +384,6 @@ fn wildcard_pat(p: &mut Parser<'_>) -> CompletedMarker {
334384
m.complete(p, WILDCARD_PAT)
335385
}
336386

337-
// test dot_dot_pat
338-
// fn main() {
339-
// let .. = ();
340-
// //
341-
// // Tuples
342-
// //
343-
// let (a, ..) = ();
344-
// let (a, ..,) = ();
345-
// let Tuple(a, ..) = ();
346-
// let Tuple(a, ..,) = ();
347-
// let (.., ..) = ();
348-
// let Tuple(.., ..) = ();
349-
// let (.., a, ..) = ();
350-
// let Tuple(.., a, ..) = ();
351-
// //
352-
// // Slices
353-
// //
354-
// let [..] = ();
355-
// let [head, ..] = ();
356-
// let [head, tail @ ..] = ();
357-
// let [head, .., cons] = ();
358-
// let [head, mid @ .., cons] = ();
359-
// let [head, .., .., cons] = ();
360-
// let [head, .., mid, tail @ ..] = ();
361-
// let [head, .., mid, .., cons] = ();
362-
// }
363-
fn rest_pat(p: &mut Parser<'_>) -> CompletedMarker {
364-
assert!(p.at(T![..]));
365-
let m = p.start();
366-
p.bump(T![..]);
367-
m.complete(p, REST_PAT)
368-
}
369-
370387
// test ref_pat
371388
// fn main() {
372389
// let &a = ();
@@ -483,6 +500,14 @@ fn box_pat(p: &mut Parser<'_>) -> CompletedMarker {
483500
// fn main() {
484501
// let const { 15 } = ();
485502
// let const { foo(); bar() } = ();
503+
//
504+
// match 42 {
505+
// const { 0 } .. const { 1 } => (),
506+
// .. const { 0 } => (),
507+
// const { 2 } .. => (),
508+
// }
509+
//
510+
// let (const { () },) = ();
486511
// }
487512
fn const_block_pat(p: &mut Parser<'_>) -> CompletedMarker {
488513
assert!(p.at(T![const]));

crates/parser/src/tests/prefix_entries.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ fn stmt() {
3333
fn pat() {
3434
check(PrefixEntryPoint::Pat, "x y", "x");
3535
check(PrefixEntryPoint::Pat, "fn f() {}", "fn");
36-
// FIXME: This one is wrong, we should consume only one pattern.
37-
check(PrefixEntryPoint::Pat, ".. ..", ".. ..");
36+
check(PrefixEntryPoint::Pat, ".. ..", "..");
3837
}
3938

4039
#[test]

crates/parser/test_data/parser/inline/ok/0156_const_block_pat.rast

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,126 @@ SOURCE_FILE
7474
L_PAREN "("
7575
R_PAREN ")"
7676
SEMICOLON ";"
77+
WHITESPACE "\n\n "
78+
EXPR_STMT
79+
MATCH_EXPR
80+
MATCH_KW "match"
81+
WHITESPACE " "
82+
LITERAL
83+
INT_NUMBER "42"
84+
WHITESPACE " "
85+
MATCH_ARM_LIST
86+
L_CURLY "{"
87+
WHITESPACE "\n "
88+
MATCH_ARM
89+
RANGE_PAT
90+
CONST_BLOCK_PAT
91+
CONST_KW "const"
92+
WHITESPACE " "
93+
BLOCK_EXPR
94+
STMT_LIST
95+
L_CURLY "{"
96+
WHITESPACE " "
97+
LITERAL
98+
INT_NUMBER "0"
99+
WHITESPACE " "
100+
R_CURLY "}"
101+
WHITESPACE " "
102+
DOT2 ".."
103+
WHITESPACE " "
104+
CONST_BLOCK_PAT
105+
CONST_KW "const"
106+
WHITESPACE " "
107+
BLOCK_EXPR
108+
STMT_LIST
109+
L_CURLY "{"
110+
WHITESPACE " "
111+
LITERAL
112+
INT_NUMBER "1"
113+
WHITESPACE " "
114+
R_CURLY "}"
115+
WHITESPACE " "
116+
FAT_ARROW "=>"
117+
WHITESPACE " "
118+
TUPLE_EXPR
119+
L_PAREN "("
120+
R_PAREN ")"
121+
COMMA ","
122+
WHITESPACE "\n "
123+
MATCH_ARM
124+
RANGE_PAT
125+
DOT2 ".."
126+
WHITESPACE " "
127+
CONST_BLOCK_PAT
128+
CONST_KW "const"
129+
WHITESPACE " "
130+
BLOCK_EXPR
131+
STMT_LIST
132+
L_CURLY "{"
133+
WHITESPACE " "
134+
LITERAL
135+
INT_NUMBER "0"
136+
WHITESPACE " "
137+
R_CURLY "}"
138+
WHITESPACE " "
139+
FAT_ARROW "=>"
140+
WHITESPACE " "
141+
TUPLE_EXPR
142+
L_PAREN "("
143+
R_PAREN ")"
144+
COMMA ","
145+
WHITESPACE "\n "
146+
MATCH_ARM
147+
RANGE_PAT
148+
CONST_BLOCK_PAT
149+
CONST_KW "const"
150+
WHITESPACE " "
151+
BLOCK_EXPR
152+
STMT_LIST
153+
L_CURLY "{"
154+
WHITESPACE " "
155+
LITERAL
156+
INT_NUMBER "2"
157+
WHITESPACE " "
158+
R_CURLY "}"
159+
WHITESPACE " "
160+
DOT2 ".."
161+
WHITESPACE " "
162+
FAT_ARROW "=>"
163+
WHITESPACE " "
164+
TUPLE_EXPR
165+
L_PAREN "("
166+
R_PAREN ")"
167+
COMMA ","
168+
WHITESPACE "\n "
169+
R_CURLY "}"
170+
WHITESPACE "\n\n "
171+
LET_STMT
172+
LET_KW "let"
173+
WHITESPACE " "
174+
TUPLE_PAT
175+
L_PAREN "("
176+
CONST_BLOCK_PAT
177+
CONST_KW "const"
178+
WHITESPACE " "
179+
BLOCK_EXPR
180+
STMT_LIST
181+
L_CURLY "{"
182+
WHITESPACE " "
183+
TUPLE_EXPR
184+
L_PAREN "("
185+
R_PAREN ")"
186+
WHITESPACE " "
187+
R_CURLY "}"
188+
COMMA ","
189+
R_PAREN ")"
190+
WHITESPACE " "
191+
EQ "="
192+
WHITESPACE " "
193+
TUPLE_EXPR
194+
L_PAREN "("
195+
R_PAREN ")"
196+
SEMICOLON ";"
77197
WHITESPACE "\n"
78198
R_CURLY "}"
79199
WHITESPACE "\n"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
fn main() {
22
let const { 15 } = ();
33
let const { foo(); bar() } = ();
4+
5+
match 42 {
6+
const { 0 } .. const { 1 } => (),
7+
.. const { 0 } => (),
8+
const { 2 } .. => (),
9+
}
10+
11+
let (const { () },) = ();
412
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
SOURCE_FILE
2+
FN
3+
FN_KW "fn"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "main"
7+
PARAM_LIST
8+
L_PAREN "("
9+
R_PAREN ")"
10+
WHITESPACE " "
11+
BLOCK_EXPR
12+
STMT_LIST
13+
L_CURLY "{"
14+
WHITESPACE "\n "
15+
MATCH_EXPR
16+
MATCH_KW "match"
17+
WHITESPACE " "
18+
LITERAL
19+
INT_NUMBER "42"
20+
WHITESPACE " "
21+
MATCH_ARM_LIST
22+
L_CURLY "{"
23+
WHITESPACE "\n "
24+
MATCH_ARM
25+
RANGE_PAT
26+
DOT2 ".."
27+
LITERAL_PAT
28+
LITERAL
29+
INT_NUMBER "0"
30+
WHITESPACE " "
31+
FAT_ARROW "=>"
32+
WHITESPACE " "
33+
BLOCK_EXPR
34+
STMT_LIST
35+
L_CURLY "{"
36+
R_CURLY "}"
37+
WHITESPACE "\n "
38+
MATCH_ARM
39+
RANGE_PAT
40+
LITERAL_PAT
41+
LITERAL
42+
INT_NUMBER "1"
43+
DOT2 ".."
44+
LITERAL_PAT
45+
LITERAL
46+
INT_NUMBER "2"
47+
WHITESPACE " "
48+
FAT_ARROW "=>"
49+
WHITESPACE " "
50+
BLOCK_EXPR
51+
STMT_LIST
52+
L_CURLY "{"
53+
R_CURLY "}"
54+
WHITESPACE "\n "
55+
R_CURLY "}"
56+
WHITESPACE "\n"
57+
R_CURLY "}"
58+
WHITESPACE "\n"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
match 42 {
3+
..0 => {}
4+
1..2 => {}
5+
}
6+
}

0 commit comments

Comments
 (0)