From fa43ef30f4f96fc8e4ea1f9c4492bcb07b3335ca Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Sat, 19 Jan 2019 01:02:38 +0100 Subject: Change parsing of struct field patterns --- crates/ra_hir/src/expr.rs | 28 +++++++++++----------- crates/ra_syntax/src/ast/generated.rs | 6 ++++- crates/ra_syntax/src/grammar.ron | 7 +++++- crates/ra_syntax/src/grammar/patterns.rs | 23 +++++++++--------- .../data/parser/inline/ok/0102_field_pat_list.txt | 22 ++++++++--------- 5 files changed, 46 insertions(+), 40 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index b52f7591d..51dae8e25 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -854,25 +854,25 @@ impl ExprCollector { ast::PatKind::PlaceholderPat(_) => Pat::Wild, ast::PatKind::StructPat(p) => { let path = p.path().and_then(Path::from_ast); - let fields = p + let field_pat_list = p .field_pat_list() - .expect("every struct should have a field list") - .pats() - .map(|f| { - let ast_pat = f.pat().expect("field pat always contains a pattern"); + .expect("every struct should have a field list"); + let mut fields: Vec<_> = field_pat_list + .bind_pats() + .map(|bind_pat| { + let ast_pat = ast::Pat::cast(bind_pat.syntax()).expect("bind pat is a pat"); let pat = self.collect_pat(ast_pat); - let name = f - .name() - .unwrap_or_else(|| { - ast::BindPat::cast(ast_pat.syntax()) - .expect("field pat without label is a bind pat") - .name() - .expect("bind pat has a name") - }) - .as_name(); + let name = bind_pat.name().expect("bind pat has a name").as_name(); FieldPat { name, pat } }) .collect(); + let iter = field_pat_list.field_pats().map(|f| { + let ast_pat = f.pat().expect("field pat always contains a pattern"); + let pat = self.collect_pat(ast_pat); + let name = f.name().expect("field pats always have a name").as_name(); + FieldPat { name, pat } + }); + fields.extend(iter); Pat::Struct { path: path, diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 23a573d74..271040bf4 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -910,7 +910,11 @@ impl AstNode for FieldPatList { impl FieldPatList { - pub fn pats(&self) -> impl Iterator { + pub fn field_pats(&self) -> impl Iterator { + super::children(self) + } + + pub fn bind_pats(&self) -> impl Iterator { super::children(self) } } diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index d8c1ae538..fc47c36d3 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -496,7 +496,12 @@ Grammar( "PlaceholderPat": (), "PathPat": ( options: [ "Path" ] ), "StructPat": ( options: ["FieldPatList", "Path"] ), - "FieldPatList": ( collections: [["pats", "FieldPat"]] ), + "FieldPatList": ( + collections: [ + ["field_pats", "FieldPat"], + ["bind_pats", "BindPat"], + ] + ), "FieldPat": ( traits: ["NameOwner"], options: ["Pat"] diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index ff9d94f8a..1ac5efdf6 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs @@ -128,7 +128,11 @@ fn field_pat_list(p: &mut Parser) { while !p.at(EOF) && !p.at(R_CURLY) { match p.current() { DOTDOT => p.bump(), - _ => field_pat(p), + IDENT if p.nth(1) == COLON => field_pat(p), + L_CURLY => error_block(p, "expected ident"), + _ => { + bind_pat(p, false); + } } if !p.at(R_CURLY) { p.expect(COMMA); @@ -139,18 +143,13 @@ fn field_pat_list(p: &mut Parser) { } fn field_pat(p: &mut Parser) { + assert!(p.at(IDENT)); + assert!(p.nth(1) == COLON); + let m = p.start(); - match p.current() { - IDENT if p.nth(1) == COLON => { - name(p); - p.bump(); - pattern(p); - } - L_CURLY => error_block(p, "expected ident"), - _ => { - bind_pat(p, false); - } - } + name(p); + p.bump(); + pattern(p); m.complete(p, FIELD_PAT); } diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0102_field_pat_list.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0102_field_pat_list.txt index ec48eada1..3f7bb10d2 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0102_field_pat_list.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0102_field_pat_list.txt @@ -43,20 +43,18 @@ SOURCE_FILE@[0; 119) FIELD_PAT_LIST@[40; 56) L_CURLY@[40; 41) WHITESPACE@[41; 42) - FIELD_PAT@[42; 43) - BIND_PAT@[42; 43) - NAME@[42; 43) - IDENT@[42; 43) "f" + BIND_PAT@[42; 43) + NAME@[42; 43) + IDENT@[42; 43) "f" COMMA@[43; 44) WHITESPACE@[44; 45) - FIELD_PAT@[45; 54) - BIND_PAT@[45; 54) - REF_KW@[45; 48) - WHITESPACE@[48; 49) - MUT_KW@[49; 52) - WHITESPACE@[52; 53) - NAME@[53; 54) - IDENT@[53; 54) "g" + BIND_PAT@[45; 54) + REF_KW@[45; 48) + WHITESPACE@[48; 49) + MUT_KW@[49; 52) + WHITESPACE@[52; 53) + NAME@[53; 54) + IDENT@[53; 54) "g" WHITESPACE@[54; 55) R_CURLY@[55; 56) WHITESPACE@[56; 57) -- cgit v1.2.3