aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/patterns.rs')
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs52
1 files changed, 42 insertions, 10 deletions
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index dd1d25b07..919b0f37d 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -2,7 +2,7 @@ use super::*;
2 2
3pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST 3pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST
4 .union(paths::PATH_FIRST) 4 .union(paths::PATH_FIRST)
5 .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS]); 5 .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS, DOT]);
6 6
7pub(crate) fn pattern(p: &mut Parser) { 7pub(crate) fn pattern(p: &mut Parser) {
8 pattern_r(p, PAT_RECOVERY_SET); 8 pattern_r(p, PAT_RECOVERY_SET);
@@ -73,6 +73,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
73 _ if paths::is_use_path_start(p) => path_pat(p), 73 _ if paths::is_use_path_start(p) => path_pat(p),
74 _ if is_literal_pat_start(p) => literal_pat(p), 74 _ if is_literal_pat_start(p) => literal_pat(p),
75 75
76 T![.] if p.at(T![..]) => dot_dot_pat(p),
76 T![_] => placeholder_pat(p), 77 T![_] => placeholder_pat(p),
77 T![&] => ref_pat(p), 78 T![&] => ref_pat(p),
78 T!['('] => tuple_pat(p), 79 T!['('] => tuple_pat(p),
@@ -163,7 +164,9 @@ fn record_field_pat_list(p: &mut Parser) {
163 p.bump_any(); 164 p.bump_any();
164 while !p.at(EOF) && !p.at(T!['}']) { 165 while !p.at(EOF) && !p.at(T!['}']) {
165 match p.current() { 166 match p.current() {
167 // A trailing `..` is *not* treated as a DOT_DOT_PAT.
166 T![.] if p.at(T![..]) => p.bump(T![..]), 168 T![.] if p.at(T![..]) => p.bump(T![..]),
169
167 IDENT if p.nth(1) == T![:] => record_field_pat(p), 170 IDENT if p.nth(1) == T![:] => record_field_pat(p),
168 T!['{'] => error_block(p, "expected ident"), 171 T!['{'] => error_block(p, "expected ident"),
169 T![box] => { 172 T![box] => {
@@ -201,6 +204,39 @@ fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
201 m.complete(p, PLACEHOLDER_PAT) 204 m.complete(p, PLACEHOLDER_PAT)
202} 205}
203 206
207// test dot_dot_pat
208// fn main() {
209// let .. = ();
210// //
211// // Tuples
212// //
213// let (a, ..) = ();
214// let (a, ..,) = ();
215// let Tuple(a, ..) = ();
216// let Tuple(a, ..,) = ();
217// let (.., ..) = ();
218// let Tuple(.., ..) = ();
219// let (.., a, ..) = ();
220// let Tuple(.., a, ..) = ();
221// //
222// // Slices
223// //
224// let [..] = ();
225// let [head, ..] = ();
226// let [head, tail @ ..] = ();
227// let [head, .., cons] = ();
228// let [head, mid @ .., cons] = ();
229// let [head, .., .., cons] = ();
230// let [head, .., mid, tail @ ..] = ();
231// let [head, .., mid, .., cons] = ();
232// }
233fn dot_dot_pat(p: &mut Parser) -> CompletedMarker {
234 assert!(p.at(T![..]));
235 let m = p.start();
236 p.bump(T![..]);
237 m.complete(p, DOT_DOT_PAT)
238}
239
204// test ref_pat 240// test ref_pat
205// fn main() { 241// fn main() {
206// let &a = (); 242// let &a = ();
@@ -241,16 +277,12 @@ fn slice_pat(p: &mut Parser) -> CompletedMarker {
241 277
242fn pat_list(p: &mut Parser, ket: SyntaxKind) { 278fn pat_list(p: &mut Parser, ket: SyntaxKind) {
243 while !p.at(EOF) && !p.at(ket) { 279 while !p.at(EOF) && !p.at(ket) {
244 match p.current() { 280 if !p.at_ts(PATTERN_FIRST) {
245 T![.] if p.at(T![..]) => p.bump(T![..]), 281 p.error("expected a pattern");
246 _ => { 282 break;
247 if !p.at_ts(PATTERN_FIRST) {
248 p.error("expected a pattern");
249 break;
250 }
251 pattern(p)
252 }
253 } 283 }
284
285 pattern(p);
254 if !p.at(ket) { 286 if !p.at(ket) {
255 p.expect(T![,]); 287 p.expect(T![,]);
256 } 288 }