diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 18 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 15 |
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::*; | |||
3 | pub(super) fn use_item(p: &mut Parser, m: Marker) { | 3 | pub(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};` |
15 | fn use_tree(p: &mut Parser) { | 15 | fn 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 | // } | ||
187 | fn record_field_pat(p: &mut Parser) { | 192 | fn 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); |