Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 89a1439

Browse files
committed
Parse exclusive range pattern
1 parent b218009 commit 89a1439

File tree

5 files changed

+116
-38
lines changed

5 files changed

+116
-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: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ pub(super) const PATTERN_FIRST: TokenSet =
1515

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

18+
/// Set of possible tokens at the start of a range pattern's end bound.
19+
const RANGE_PAT_END_FIRST: TokenSet =
20+
expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-]]));
21+
1822
pub(crate) fn pattern(p: &mut Parser<'_>) {
1923
pattern_r(p, PAT_RECOVERY_SET);
2024
}
@@ -105,6 +109,52 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
105109
return;
106110
}
107111

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

176-
T![.] if p.at(T![..]) => rest_pat(p),
177226
T![_] => wildcard_pat(p),
178227
T![&] => ref_pat(p),
179228
T!['('] => tuple_pat(p),
@@ -334,39 +383,6 @@ fn wildcard_pat(p: &mut Parser<'_>) -> CompletedMarker {
334383
m.complete(p, WILDCARD_PAT)
335384
}
336385

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-
370386
// test ref_pat
371387
// fn main() {
372388
// let &a = ();

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]
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)