diff options
author | Aleksey Kladov <[email protected]> | 2019-09-20 14:53:05 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-09-20 14:57:31 +0100 |
commit | d57b993adec18a4629b0a1669f2ee714984d8536 (patch) | |
tree | 89029800ca9ae0dddd2515ef869fa06a6f8ff5c3 /crates/ra_parser | |
parent | c73399365867178523885d0c997844d0d2d33325 (diff) |
fix infinite loop in the parser
closes #1866
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar/items/use_item.rs | 18 |
1 files changed, 11 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 | } |