diff options
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 18 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0036_partial_use.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0036_partial_use.txt | 51 |
3 files changed, 64 insertions, 7 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_syntax/test_data/parser/err/0036_partial_use.rs b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs new file mode 100644 index 000000000..d521a5bb2 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | use std::{error::Error; | ||
2 | use std::io; | ||
diff --git a/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt new file mode 100644 index 000000000..181f408c8 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/err/0036_partial_use.txt | |||
@@ -0,0 +1,51 @@ | |||
1 | SOURCE_FILE@[0; 37) | ||
2 | USE_ITEM@[0; 36) | ||
3 | USE_KW@[0; 3) "use" | ||
4 | WHITESPACE@[3; 4) " " | ||
5 | USE_TREE@[4; 36) | ||
6 | PATH@[4; 7) | ||
7 | PATH_SEGMENT@[4; 7) | ||
8 | NAME_REF@[4; 7) | ||
9 | IDENT@[4; 7) "std" | ||
10 | COLONCOLON@[7; 9) "::" | ||
11 | USE_TREE_LIST@[9; 36) | ||
12 | L_CURLY@[9; 10) "{" | ||
13 | USE_TREE@[10; 22) | ||
14 | PATH@[10; 22) | ||
15 | PATH@[10; 15) | ||
16 | PATH_SEGMENT@[10; 15) | ||
17 | NAME_REF@[10; 15) | ||
18 | IDENT@[10; 15) "error" | ||
19 | COLONCOLON@[15; 17) "::" | ||
20 | PATH_SEGMENT@[17; 22) | ||
21 | NAME_REF@[17; 22) | ||
22 | IDENT@[17; 22) "Error" | ||
23 | ERROR@[22; 23) | ||
24 | SEMI@[22; 23) ";" | ||
25 | WHITESPACE@[23; 24) "\n" | ||
26 | ERROR@[24; 27) | ||
27 | USE_KW@[24; 27) "use" | ||
28 | WHITESPACE@[27; 28) " " | ||
29 | USE_TREE@[28; 35) | ||
30 | PATH@[28; 35) | ||
31 | PATH@[28; 31) | ||
32 | PATH_SEGMENT@[28; 31) | ||
33 | NAME_REF@[28; 31) | ||
34 | IDENT@[28; 31) "std" | ||
35 | COLONCOLON@[31; 33) "::" | ||
36 | PATH_SEGMENT@[33; 35) | ||
37 | NAME_REF@[33; 35) | ||
38 | IDENT@[33; 35) "io" | ||
39 | ERROR@[35; 36) | ||
40 | SEMI@[35; 36) ";" | ||
41 | WHITESPACE@[36; 37) "\n" | ||
42 | error 22: expected COMMA | ||
43 | error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
44 | error 23: expected COMMA | ||
45 | error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
46 | error 27: expected COMMA | ||
47 | error 35: expected COMMA | ||
48 | error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier | ||
49 | error 36: expected COMMA | ||
50 | error 36: expected R_CURLY | ||
51 | error 36: expected SEMI | ||