Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir_def/src/body/lower.rs | 2 | ||||
| -rw-r--r-- | crates/parser/src/grammar/patterns.rs | 68 | ||||
| -rw-r--r-- | crates/syntax/Cargo.toml | 2 | ||||
| -rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 4 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/inline/ok/0008_path_part.rast | 3 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast | 58 | ||||
| -rw-r--r-- | crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs | 1 |
7 files changed, 101 insertions, 37 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 4c1a3344ec..372cf9aba8 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -818,7 +818,7 @@ impl ExprCollector<'_> { let ellipsis = p .record_pat_field_list() .expect("every struct should have a field list") - .dotdot_token() + .rest_pat() .is_some(); Pat::Record { path, args, ellipsis } diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 5fe1a7b13b..9da94ce162 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -205,46 +205,64 @@ fn tuple_pat_fields(p: &mut Parser) { p.expect(T![')']); } +// test record_pat_field +// fn foo() { +// let S { 0: 1 } = (); +// let S { x: 1 } = (); +// let S { #[cfg(any())] x: 1 } = (); +// } +fn record_pat_field(p: &mut Parser) { + match p.current() { + IDENT | INT_NUMBER if p.nth(1) == T![:] => { + name_ref_or_index(p); + p.bump(T![:]); + pattern(p); + } + T![.] => { + if p.at(T![..]) { + p.bump(T![..]); + } else { + ident_pat(p, false); + } + } + T![box] => { + // FIXME: not all box patterns should be allowed + box_pat(p); + } + _ => { + ident_pat(p, false); + } + } +} + // test record_pat_field_list // fn foo() { // let S {} = (); // let S { f, ref mut g } = (); // let S { h: _, ..} = (); // let S { h: _, } = (); +// let S { #[cfg(any())] .. } = (); // } fn record_pat_field_list(p: &mut Parser) { assert!(p.at(T!['{'])); let m = p.start(); p.bump(T!['{']); while !p.at(EOF) && !p.at(T!['}']) { + let m = p.start(); + attributes::outer_attrs(p); + match p.current() { // A trailing `..` is *not* treated as a REST_PAT. - T![.] if p.at(T![..]) => p.bump(T![..]), - T!['{'] => error_block(p, "expected ident"), - + T![.] if p.at(T![..]) => { + p.bump(T![..]); + m.complete(p, REST_PAT); + } + T!['{'] => { + error_block(p, "expected ident"); + m.abandon(p); + } _ => { - let m = p.start(); - attributes::outer_attrs(p); - match p.current() { - // test record_pat_field - // fn foo() { - // let S { 0: 1 } = (); - // let S { x: 1 } = (); - // let S { #[cfg(any())] x: 1 } = (); - // } - IDENT | INT_NUMBER if p.nth(1) == T![:] => { - name_ref_or_index(p); - p.bump(T![:]); - pattern(p); - } - T![box] => { - // FIXME: not all box patterns should be allowed - box_pat(p); - } - _ => { - ident_pat(p, false); - } - } + record_pat_field(p); m.complete(p, RECORD_PAT_FIELD); } } diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index f889fa2a2c..3c5adb97fb 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -29,7 +29,7 @@ rayon = "1" expect-test = "1.1" proc-macro2 = "1.0.8" quote = "1.0.2" -ungrammar = "=1.14.5" +ungrammar = "=1.14.6" test_utils = { path = "../test_utils" } sourcegen = { path = "../sourcegen" } diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 1810033e84..f69c873663 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -1290,6 +1290,7 @@ impl BoxPat { pub struct RestPat { pub(crate) syntax: SyntaxNode, } +impl ast::HasAttrs for RestPat {} impl RestPat { pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) } } @@ -1418,7 +1419,7 @@ pub struct RecordPatFieldList { impl RecordPatFieldList { pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } pub fn fields(&self) -> AstChildren<RecordPatField> { support::children(&self.syntax) } - pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) } + pub fn rest_pat(&self) -> Option<RestPat> { support::child(&self.syntax) } pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } } @@ -3836,6 +3837,7 @@ impl AstNode for AnyHasAttrs { | MATCH_ARM_LIST | MATCH_ARM | IDENT_PAT + | REST_PAT | RECORD_PAT_FIELD => true, _ => false, } diff --git a/crates/syntax/test_data/parser/inline/ok/0008_path_part.rast b/crates/syntax/test_data/parser/inline/ok/0008_path_part.rast index ff81307128..c20e41ffae 100644 --- a/crates/syntax/test_data/parser/inline/ok/0008_path_part.rast +++ b/crates/syntax/test_data/parser/inline/ok/0008_path_part.rast @@ -62,7 +62,8 @@ [email protected] - [email protected] ".." + [email protected] ".." diff --git a/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast index 4c44da9d55..761438d2ec 100644 --- a/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast +++ b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast @@ -1,5 +1,5 @@ [email protected] "fn" @@ -8,8 +8,8 @@ [email protected] [email protected] "\n " @@ -89,7 +89,8 @@ [email protected] - [email protected] ".." + [email protected] ".." @@ -128,6 +129,47 @@ [email protected] - [email protected] "\n" - [email protected] "}" - [email protected] "\n" + [email protected] "\n " + [email protected] "let" + [email protected] " " + [email protected] "S" + [email protected] " " + [email protected] "{" + [email protected] " " + [email protected] "#" + [email protected] "[" + [email protected] "cfg" + [email protected] "(" + [email protected] "any" + [email protected] "(" + [email protected] ")" + [email protected] ")" + [email protected] "]" + [email protected] " " + [email protected] ".." + [email protected] " " + [email protected] "}" + [email protected] " " + [email protected] "=" + [email protected] " " + [email protected] "(" + [email protected] ")" + [email protected] ";" + [email protected] "\n" + [email protected] "}" + [email protected] "\n" diff --git a/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs index da3412fa8a..0bfaae7c4d 100644 --- a/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs +++ b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs @@ -3,4 +3,5 @@ fn foo() { let S { f, ref mut g } = (); let S { h: _, ..} = (); let S { h: _, } = (); + let S { #[cfg(any())] .. } = (); } |