aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/items/use_item.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-09-20 14:53:05 +0100
committerAleksey Kladov <[email protected]>2019-09-20 14:57:31 +0100
commitd57b993adec18a4629b0a1669f2ee714984d8536 (patch)
tree89029800ca9ae0dddd2515ef869fa06a6f8ff5c3 /crates/ra_parser/src/grammar/items/use_item.rs
parentc73399365867178523885d0c997844d0d2d33325 (diff)
fix infinite loop in the parser
closes #1866
Diffstat (limited to 'crates/ra_parser/src/grammar/items/use_item.rs')
-rw-r--r--crates/ra_parser/src/grammar/items/use_item.rs18
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::*;
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 }