aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/expr.rs28
-rw-r--r--crates/ra_syntax/src/ast/generated.rs6
-rw-r--r--crates/ra_syntax/src/grammar.ron7
-rw-r--r--crates/ra_syntax/src/grammar/patterns.rs23
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0102_field_pat_list.txt22
5 files changed, 46 insertions, 40 deletions
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 {
854 ast::PatKind::PlaceholderPat(_) => Pat::Wild, 854 ast::PatKind::PlaceholderPat(_) => Pat::Wild,
855 ast::PatKind::StructPat(p) => { 855 ast::PatKind::StructPat(p) => {
856 let path = p.path().and_then(Path::from_ast); 856 let path = p.path().and_then(Path::from_ast);
857 let fields = p 857 let field_pat_list = p
858 .field_pat_list() 858 .field_pat_list()
859 .expect("every struct should have a field list") 859 .expect("every struct should have a field list");
860 .pats() 860 let mut fields: Vec<_> = field_pat_list
861 .map(|f| { 861 .bind_pats()
862 let ast_pat = f.pat().expect("field pat always contains a pattern"); 862 .map(|bind_pat| {
863 let ast_pat = ast::Pat::cast(bind_pat.syntax()).expect("bind pat is a pat");
863 let pat = self.collect_pat(ast_pat); 864 let pat = self.collect_pat(ast_pat);
864 let name = f 865 let name = bind_pat.name().expect("bind pat has a name").as_name();
865 .name()
866 .unwrap_or_else(|| {
867 ast::BindPat::cast(ast_pat.syntax())
868 .expect("field pat without label is a bind pat")
869 .name()
870 .expect("bind pat has a name")
871 })
872 .as_name();
873 FieldPat { name, pat } 866 FieldPat { name, pat }
874 }) 867 })
875 .collect(); 868 .collect();
869 let iter = field_pat_list.field_pats().map(|f| {
870 let ast_pat = f.pat().expect("field pat always contains a pattern");
871 let pat = self.collect_pat(ast_pat);
872 let name = f.name().expect("field pats always have a name").as_name();
873 FieldPat { name, pat }
874 });
875 fields.extend(iter);
876 876
877 Pat::Struct { 877 Pat::Struct {
878 path: path, 878 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 {
910 910
911 911
912impl FieldPatList { 912impl FieldPatList {
913 pub fn pats(&self) -> impl Iterator<Item = &FieldPat> { 913 pub fn field_pats(&self) -> impl Iterator<Item = &FieldPat> {
914 super::children(self)
915 }
916
917 pub fn bind_pats(&self) -> impl Iterator<Item = &BindPat> {
914 super::children(self) 918 super::children(self)
915 } 919 }
916} 920}
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(
496 "PlaceholderPat": (), 496 "PlaceholderPat": (),
497 "PathPat": ( options: [ "Path" ] ), 497 "PathPat": ( options: [ "Path" ] ),
498 "StructPat": ( options: ["FieldPatList", "Path"] ), 498 "StructPat": ( options: ["FieldPatList", "Path"] ),
499 "FieldPatList": ( collections: [["pats", "FieldPat"]] ), 499 "FieldPatList": (
500 collections: [
501 ["field_pats", "FieldPat"],
502 ["bind_pats", "BindPat"],
503 ]
504 ),
500 "FieldPat": ( 505 "FieldPat": (
501 traits: ["NameOwner"], 506 traits: ["NameOwner"],
502 options: ["Pat"] 507 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) {
128 while !p.at(EOF) && !p.at(R_CURLY) { 128 while !p.at(EOF) && !p.at(R_CURLY) {
129 match p.current() { 129 match p.current() {
130 DOTDOT => p.bump(), 130 DOTDOT => p.bump(),
131 _ => field_pat(p), 131 IDENT if p.nth(1) == COLON => field_pat(p),
132 L_CURLY => error_block(p, "expected ident"),
133 _ => {
134 bind_pat(p, false);
135 }
132 } 136 }
133 if !p.at(R_CURLY) { 137 if !p.at(R_CURLY) {
134 p.expect(COMMA); 138 p.expect(COMMA);
@@ -139,18 +143,13 @@ fn field_pat_list(p: &mut Parser) {
139} 143}
140 144
141fn field_pat(p: &mut Parser) { 145fn field_pat(p: &mut Parser) {
146 assert!(p.at(IDENT));
147 assert!(p.nth(1) == COLON);
148
142 let m = p.start(); 149 let m = p.start();
143 match p.current() { 150 name(p);
144 IDENT if p.nth(1) == COLON => { 151 p.bump();
145 name(p); 152 pattern(p);
146 p.bump();
147 pattern(p);
148 }
149 L_CURLY => error_block(p, "expected ident"),
150 _ => {
151 bind_pat(p, false);
152 }
153 }
154 m.complete(p, FIELD_PAT); 153 m.complete(p, FIELD_PAT);
155} 154}
156 155
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)
43 FIELD_PAT_LIST@[40; 56) 43 FIELD_PAT_LIST@[40; 56)
44 L_CURLY@[40; 41) 44 L_CURLY@[40; 41)
45 WHITESPACE@[41; 42) 45 WHITESPACE@[41; 42)
46 FIELD_PAT@[42; 43) 46 BIND_PAT@[42; 43)
47 BIND_PAT@[42; 43) 47 NAME@[42; 43)
48 NAME@[42; 43) 48 IDENT@[42; 43) "f"
49 IDENT@[42; 43) "f"
50 COMMA@[43; 44) 49 COMMA@[43; 44)
51 WHITESPACE@[44; 45) 50 WHITESPACE@[44; 45)
52 FIELD_PAT@[45; 54) 51 BIND_PAT@[45; 54)
53 BIND_PAT@[45; 54) 52 REF_KW@[45; 48)
54 REF_KW@[45; 48) 53 WHITESPACE@[48; 49)
55 WHITESPACE@[48; 49) 54 MUT_KW@[49; 52)
56 MUT_KW@[49; 52) 55 WHITESPACE@[52; 53)
57 WHITESPACE@[52; 53) 56 NAME@[53; 54)
58 NAME@[53; 54) 57 IDENT@[53; 54) "g"
59 IDENT@[53; 54) "g"
60 WHITESPACE@[54; 55) 58 WHITESPACE@[54; 55)
61 R_CURLY@[55; 56) 59 R_CURLY@[55; 56)
62 WHITESPACE@[56; 57) 60 WHITESPACE@[56; 57)