diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index 46034942a93e..fbc3fe001bc8 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs @@ -145,7 +145,21 @@ fn path_pat(p: &mut Parser) -> CompletedMarker { fn tuple_pat_fields(p: &mut Parser) { assert!(p.at(T!['('])); p.bump(); - pat_list(p, T![')']); + while !p.at(EOF) && !p.at(T![')']) { + match p.current() { + T![..] => p.bump(), + _ => { + if !p.at_ts(PATTERN_FIRST) { + p.error("expected a pattern"); + break; + } + pattern(p) + } + } + if !p.at(T![')']) { + p.expect(T![,]); + } + } p.expect(T![')']); } @@ -225,20 +239,21 @@ fn tuple_pat(p: &mut Parser) -> CompletedMarker { // test slice_pat // fn main() { // let [a, b, ..] = []; +// let [a, b..] = []; // } fn slice_pat(p: &mut Parser) -> CompletedMarker { assert!(p.at(T!['['])); let m = p.start(); p.bump(); - pat_list(p, T![']']); - p.expect(T![']']); - m.complete(p, SLICE_PAT) -} - -fn pat_list(p: &mut Parser, ket: SyntaxKind) { - while !p.at(EOF) && !p.at(ket) { + while !p.at(EOF) && !p.at(T![']']) { match p.current() { T![..] => p.bump(), + IDENT if p.nth(1) == T![..] => { + let m_sub = p.start(); + p.bump(); + p.bump(); + m_sub.complete(p, SUBSLICE_PAT); + } _ => { if !p.at_ts(PATTERN_FIRST) { p.error("expected a pattern"); @@ -247,10 +262,12 @@ fn pat_list(p: &mut Parser, ket: SyntaxKind) { pattern(p) } } - if !p.at(ket) { + if !p.at(T![']']) { p.expect(T![,]); } } + p.expect(T![']']); + m.complete(p, SLICE_PAT) } // test bind_pat diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 374fd5aec584..53a2142ecd35 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -165,6 +165,7 @@ pub enum SyntaxKind { SLICE_PAT, RANGE_PAT, LITERAL_PAT, + SUBSLICE_PAT, TUPLE_EXPR, ARRAY_EXPR, PAREN_EXPR, @@ -632,6 +633,7 @@ impl SyntaxKind { SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, LITERAL_PAT => &SyntaxInfo { name: "LITERAL_PAT" }, + SUBSLICE_PAT => &SyntaxInfo { name: "SUBSLICE_PAT" }, TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 6c075a700f78..71aec1fe33f3 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -168,6 +168,7 @@ Grammar( "SLICE_PAT", "RANGE_PAT", "LITERAL_PAT", + "SUBSLICE_PAT", // atoms "TUPLE_EXPR", @@ -686,7 +687,7 @@ Grammar( "LifetimeArg": (), "MacroItems": ( - traits: [ "ModuleItemOwner", "FnDefOwner" ], + traits: [ "ModuleItemOwner", "FnDefOwner" ], ), "MacroStmts" : ( diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.rs index 7955973b952a..0aa2178a4978 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.rs +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.rs @@ -1,3 +1,4 @@ fn main() { let [a, b, ..] = []; + let [a, b..] = []; } diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.txt index 40ddbfbf602c..4c8d2030d0c6 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0024_slice_pat.txt @@ -1,5 +1,5 @@ -SOURCE_FILE@[0; 39) - FN_DEF@[0; 38) +SOURCE_FILE@[0; 62) + FN_DEF@[0; 61) FN_KW@[0; 2) "fn" WHITESPACE@[2; 3) " " NAME@[3; 7) @@ -8,7 +8,7 @@ SOURCE_FILE@[0; 39) L_PAREN@[7; 8) "(" R_PAREN@[8; 9) ")" WHITESPACE@[9; 10) " " - BLOCK@[10; 38) + BLOCK@[10; 61) L_CURLY@[10; 11) "{" WHITESPACE@[11; 16) "\n " LET_STMT@[16; 36) @@ -35,6 +35,28 @@ SOURCE_FILE@[0; 39) L_BRACK@[33; 34) "[" R_BRACK@[34; 35) "]" SEMI@[35; 36) ";" - WHITESPACE@[36; 37) "\n" - R_CURLY@[37; 38) "}" - WHITESPACE@[38; 39) "\n" + WHITESPACE@[36; 41) "\n " + LET_STMT@[41; 59) + LET_KW@[41; 44) "let" + WHITESPACE@[44; 45) " " + SLICE_PAT@[45; 53) + L_BRACK@[45; 46) "[" + BIND_PAT@[46; 47) + NAME@[46; 47) + IDENT@[46; 47) "a" + COMMA@[47; 48) "," + WHITESPACE@[48; 49) " " + SUBSLICE_PAT@[49; 52) + IDENT@[49; 50) "b" + DOTDOT@[50; 52) ".." + R_BRACK@[52; 53) "]" + WHITESPACE@[53; 54) " " + EQ@[54; 55) "=" + WHITESPACE@[55; 56) " " + ARRAY_EXPR@[56; 58) + L_BRACK@[56; 57) "[" + R_BRACK@[57; 58) "]" + SEMI@[58; 59) ";" + WHITESPACE@[59; 60) "\n" + R_CURLY@[60; 61) "}" + WHITESPACE@[61; 62) "\n"