aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser')
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs18
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs15
2 files changed, 23 insertions, 10 deletions
diff --git a/crates/ra_parser/src/grammar/items/use_item.rs b/crates/ra_parser/src/grammar/items/use_item.rs
index 2af2ad315..63ac37e9e 100644
--- a/crates/ra_parser/src/grammar/items/use_item.rs
+++ b/crates/ra_parser/src/grammar/items/use_item.rs
@@ -3,7 +3,7 @@ use super::*;
3pub(super) fn use_item(p: &mut Parser, m: Marker) { 3pub(super) fn use_item(p: &mut Parser, m: Marker) {
4 assert!(p.at(T![use])); 4 assert!(p.at(T![use]));
5 p.bump(T![use]); 5 p.bump(T![use]);
6 use_tree(p); 6 use_tree(p, true);
7 p.expect(T![;]); 7 p.expect(T![;]);
8 m.complete(p, USE_ITEM); 8 m.complete(p, USE_ITEM);
9} 9}
@@ -12,7 +12,7 @@ pub(super) fn use_item(p: &mut Parser, m: Marker) {
12/// Note that this is called both by `use_item` and `use_tree_list`, 12/// Note that this is called both by `use_item` and `use_tree_list`,
13/// so handles both `some::path::{inner::path}` and `inner::path` in 13/// so handles both `some::path::{inner::path}` and `inner::path` in
14/// `use some::path::{inner::path};` 14/// `use some::path::{inner::path};`
15fn use_tree(p: &mut Parser) { 15fn use_tree(p: &mut Parser, top_level: bool) {
16 let m = p.start(); 16 let m = p.start();
17 match p.current() { 17 match p.current() {
18 // Finish the use_tree for cases of e.g. 18 // Finish the use_tree for cases of e.g.
@@ -101,10 +101,14 @@ fn use_tree(p: &mut Parser) {
101 } 101 }
102 _ => { 102 _ => {
103 m.abandon(p); 103 m.abandon(p);
104 p.err_recover( 104 let msg = "expected one of `*`, `::`, `{`, `self`, `super` or an identifier";
105 "expected one of `*`, `::`, `{`, `self`, `super` or an identifier", 105 if top_level {
106 ITEM_RECOVERY_SET, 106 p.err_recover(msg, ITEM_RECOVERY_SET);
107 ); 107 } else {
108 // if we are parsing a nested tree, we have to eat a token to
109 // main balanced `{}`
110 p.err_and_bump(msg);
111 }
108 return; 112 return;
109 } 113 }
110 } 114 }
@@ -116,7 +120,7 @@ pub(crate) fn use_tree_list(p: &mut Parser) {
116 let m = p.start(); 120 let m = p.start();
117 p.bump(T!['{']); 121 p.bump(T!['{']);
118 while !p.at(EOF) && !p.at(T!['}']) { 122 while !p.at(EOF) && !p.at(T!['}']) {
119 use_tree(p); 123 use_tree(p, false);
120 if !p.at(T!['}']) { 124 if !p.at(T!['}']) {
121 p.expect(T![,]); 125 p.expect(T![,]);
122 } 126 }
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index a4ffd6960..aa9a6d18e 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -167,7 +167,7 @@ fn record_field_pat_list(p: &mut Parser) {
167 // A trailing `..` is *not* treated as a DOT_DOT_PAT. 167 // A trailing `..` is *not* treated as a DOT_DOT_PAT.
168 T![.] if p.at(T![..]) => p.bump(T![..]), 168 T![.] if p.at(T![..]) => p.bump(T![..]),
169 169
170 IDENT if p.nth(1) == T![:] => record_field_pat(p), 170 IDENT | INT_NUMBER if p.nth(1) == T![:] => record_field_pat(p),
171 T!['{'] => error_block(p, "expected ident"), 171 T!['{'] => error_block(p, "expected ident"),
172 T![box] => { 172 T![box] => {
173 box_pat(p); 173 box_pat(p);
@@ -184,12 +184,21 @@ fn record_field_pat_list(p: &mut Parser) {
184 m.complete(p, RECORD_FIELD_PAT_LIST); 184 m.complete(p, RECORD_FIELD_PAT_LIST);
185} 185}
186 186
187// test record_field_pat
188// fn foo() {
189// let S { 0: 1 } = ();
190// let S { x: 1 } = ();
191// }
187fn record_field_pat(p: &mut Parser) { 192fn record_field_pat(p: &mut Parser) {
188 assert!(p.at(IDENT)); 193 assert!(p.at(IDENT) || p.at(INT_NUMBER));
189 assert!(p.nth(1) == T![:]); 194 assert!(p.nth(1) == T![:]);
190 195
191 let m = p.start(); 196 let m = p.start();
192 name(p); 197
198 if !p.eat(INT_NUMBER) {
199 name(p)
200 }
201
193 p.bump_any(); 202 p.bump_any();
194 pattern(p); 203 pattern(p);
195 m.complete(p, RECORD_FIELD_PAT); 204 m.complete(p, RECORD_FIELD_PAT);