Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/patterns.rs')
| -rw-r--r-- | crates/parser/src/grammar/patterns.rs | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 5f4977886f..baa93aa083 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -15,6 +15,10 @@ pub(super) const PATTERN_FIRST: TokenSet = const PAT_TOP_FIRST: TokenSet = PATTERN_FIRST.union(TokenSet::new(&[T![|]])); +/// Set of possible tokens at the start of a range pattern's end bound. +const RANGE_PAT_END_FIRST: TokenSet = + expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[T![-]])); + pub(crate) fn pattern(p: &mut Parser<'_>) { pattern_r(p, PAT_RECOVERY_SET); } @@ -105,6 +109,52 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) { return; } + // test exclusive_range_pat + // fn main() { + // match 42 { + // ..0 => {} + // 1..2 => {} + // } + // } + + // test dot_dot_pat + // fn main() { + // let .. = (); + // // + // // Tuples + // // + // let (a, ..) = (); + // let (a, ..,) = (); + // let Tuple(a, ..) = (); + // let Tuple(a, ..,) = (); + // let (.., ..) = (); + // let Tuple(.., ..) = (); + // let (.., a, ..) = (); + // let Tuple(.., a, ..) = (); + // // + // // Slices + // // + // let [..] = (); + // let [head, ..] = (); + // let [head, tail @ ..] = (); + // let [head, .., cons] = (); + // let [head, mid @ .., cons] = (); + // let [head, .., .., cons] = (); + // let [head, .., mid, tail @ ..] = (); + // let [head, .., mid, .., cons] = (); + // } + if p.at(T![..]) { + let m = p.start(); + p.bump(T![..]); + if p.at_ts(RANGE_PAT_END_FIRST) { + atom_pat(p, recovery_set); + m.complete(p, RANGE_PAT); + } else { + m.complete(p, REST_PAT); + } + return; + } + if let Some(lhs) = atom_pat(p, recovery_set) { for range_op in [T![...], T![..=], T![..]] { if p.at(range_op) { @@ -173,7 +223,6 @@ fn atom_pat(p: &mut Parser<'_>, recovery_set: TokenSet) -> Option<CompletedMarke _ if paths::is_path_start(p) => path_or_macro_pat(p), _ if is_literal_pat_start(p) => literal_pat(p), - T![.] if p.at(T![..]) => rest_pat(p), T![_] => wildcard_pat(p), T![&] => ref_pat(p), T!['('] => tuple_pat(p), @@ -334,39 +383,6 @@ fn wildcard_pat(p: &mut Parser<'_>) -> CompletedMarker { m.complete(p, WILDCARD_PAT) } -// test dot_dot_pat -// fn main() { -// let .. = (); -// // -// // Tuples -// // -// let (a, ..) = (); -// let (a, ..,) = (); -// let Tuple(a, ..) = (); -// let Tuple(a, ..,) = (); -// let (.., ..) = (); -// let Tuple(.., ..) = (); -// let (.., a, ..) = (); -// let Tuple(.., a, ..) = (); -// // -// // Slices -// // -// let [..] = (); -// let [head, ..] = (); -// let [head, tail @ ..] = (); -// let [head, .., cons] = (); -// let [head, mid @ .., cons] = (); -// let [head, .., .., cons] = (); -// let [head, .., mid, tail @ ..] = (); -// let [head, .., mid, .., cons] = (); -// } -fn rest_pat(p: &mut Parser<'_>) -> CompletedMarker { - assert!(p.at(T![..])); - let m = p.start(); - p.bump(T![..]); - m.complete(p, REST_PAT) -} - // test ref_pat // fn main() { // let &a = (); |