Merge #1882
1882: fix infinite loop in the parser r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
24ac228c39
|
@ -3,7 +3,7 @@ use super::*;
|
||||||
pub(super) fn use_item(p: &mut Parser, m: Marker) {
|
pub(super) fn use_item(p: &mut Parser, m: Marker) {
|
||||||
assert!(p.at(T![use]));
|
assert!(p.at(T![use]));
|
||||||
p.bump(T![use]);
|
p.bump(T![use]);
|
||||||
use_tree(p);
|
use_tree(p, true);
|
||||||
p.expect(T![;]);
|
p.expect(T![;]);
|
||||||
m.complete(p, USE_ITEM);
|
m.complete(p, USE_ITEM);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ pub(super) fn use_item(p: &mut Parser, m: Marker) {
|
||||||
/// Note that this is called both by `use_item` and `use_tree_list`,
|
/// Note that this is called both by `use_item` and `use_tree_list`,
|
||||||
/// so handles both `some::path::{inner::path}` and `inner::path` in
|
/// so handles both `some::path::{inner::path}` and `inner::path` in
|
||||||
/// `use some::path::{inner::path};`
|
/// `use some::path::{inner::path};`
|
||||||
fn use_tree(p: &mut Parser) {
|
fn use_tree(p: &mut Parser, top_level: bool) {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
match p.current() {
|
match p.current() {
|
||||||
// Finish the use_tree for cases of e.g.
|
// Finish the use_tree for cases of e.g.
|
||||||
|
@ -101,10 +101,14 @@ fn use_tree(p: &mut Parser) {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
p.err_recover(
|
let msg = "expected one of `*`, `::`, `{`, `self`, `super` or an identifier";
|
||||||
"expected one of `*`, `::`, `{`, `self`, `super` or an identifier",
|
if top_level {
|
||||||
ITEM_RECOVERY_SET,
|
p.err_recover(msg, ITEM_RECOVERY_SET);
|
||||||
);
|
} else {
|
||||||
|
// if we are parsing a nested tree, we have to eat a token to
|
||||||
|
// main balanced `{}`
|
||||||
|
p.err_and_bump(msg);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +120,7 @@ pub(crate) fn use_tree_list(p: &mut Parser) {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T!['{']);
|
p.bump(T!['{']);
|
||||||
while !p.at(EOF) && !p.at(T!['}']) {
|
while !p.at(EOF) && !p.at(T!['}']) {
|
||||||
use_tree(p);
|
use_tree(p, false);
|
||||||
if !p.at(T!['}']) {
|
if !p.at(T!['}']) {
|
||||||
p.expect(T![,]);
|
p.expect(T![,]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
use std::{error::Error;
|
||||||
|
use std::io;
|
51
crates/ra_syntax/test_data/parser/err/0036_partial_use.txt
Normal file
51
crates/ra_syntax/test_data/parser/err/0036_partial_use.txt
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
SOURCE_FILE@[0; 37)
|
||||||
|
USE_ITEM@[0; 36)
|
||||||
|
USE_KW@[0; 3) "use"
|
||||||
|
WHITESPACE@[3; 4) " "
|
||||||
|
USE_TREE@[4; 36)
|
||||||
|
PATH@[4; 7)
|
||||||
|
PATH_SEGMENT@[4; 7)
|
||||||
|
NAME_REF@[4; 7)
|
||||||
|
IDENT@[4; 7) "std"
|
||||||
|
COLONCOLON@[7; 9) "::"
|
||||||
|
USE_TREE_LIST@[9; 36)
|
||||||
|
L_CURLY@[9; 10) "{"
|
||||||
|
USE_TREE@[10; 22)
|
||||||
|
PATH@[10; 22)
|
||||||
|
PATH@[10; 15)
|
||||||
|
PATH_SEGMENT@[10; 15)
|
||||||
|
NAME_REF@[10; 15)
|
||||||
|
IDENT@[10; 15) "error"
|
||||||
|
COLONCOLON@[15; 17) "::"
|
||||||
|
PATH_SEGMENT@[17; 22)
|
||||||
|
NAME_REF@[17; 22)
|
||||||
|
IDENT@[17; 22) "Error"
|
||||||
|
ERROR@[22; 23)
|
||||||
|
SEMI@[22; 23) ";"
|
||||||
|
WHITESPACE@[23; 24) "\n"
|
||||||
|
ERROR@[24; 27)
|
||||||
|
USE_KW@[24; 27) "use"
|
||||||
|
WHITESPACE@[27; 28) " "
|
||||||
|
USE_TREE@[28; 35)
|
||||||
|
PATH@[28; 35)
|
||||||
|
PATH@[28; 31)
|
||||||
|
PATH_SEGMENT@[28; 31)
|
||||||
|
NAME_REF@[28; 31)
|
||||||
|
IDENT@[28; 31) "std"
|
||||||
|
COLONCOLON@[31; 33) "::"
|
||||||
|
PATH_SEGMENT@[33; 35)
|
||||||
|
NAME_REF@[33; 35)
|
||||||
|
IDENT@[33; 35) "io"
|
||||||
|
ERROR@[35; 36)
|
||||||
|
SEMI@[35; 36) ";"
|
||||||
|
WHITESPACE@[36; 37) "\n"
|
||||||
|
error 22: expected COMMA
|
||||||
|
error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
|
||||||
|
error 23: expected COMMA
|
||||||
|
error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
|
||||||
|
error 27: expected COMMA
|
||||||
|
error 35: expected COMMA
|
||||||
|
error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
|
||||||
|
error 36: expected COMMA
|
||||||
|
error 36: expected R_CURLY
|
||||||
|
error 36: expected SEMI
|
Loading…
Reference in a new issue