mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Auto merge of #16349 - Young-Flash:use_error_recovery, r=Veykril
fix: add error recovery for use_tree_list parsing This PR adds error recovery for USE_TREE_LIST parsing, avoid the wrong USE_TREE_LIST making the rest parsing incorrectly. before  after  close https://github.com/rust-lang/rust-analyzer/issues/16227
This commit is contained in:
commit
1ab8c7fd27
5 changed files with 112 additions and 38 deletions
|
@ -8,6 +8,33 @@ fn check(ra_fixture: &str, expect: Expect) {
|
||||||
expect.assert_eq(&actual)
|
expect.assert_eq(&actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn use_tree_completion() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct implThing;
|
||||||
|
|
||||||
|
use crate::{impl$0};
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
st implThing implThing
|
||||||
|
kw self
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct implThing;
|
||||||
|
|
||||||
|
use crate::{impl$0;
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
st implThing implThing
|
||||||
|
kw self
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn use_tree_start() {
|
fn use_tree_start() {
|
||||||
cov_mark::check!(unqualified_path_selected_only);
|
cov_mark::check!(unqualified_path_selected_only);
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub(super) fn use_(p: &mut Parser<'_>, m: Marker) {
|
||||||
|
|
||||||
// test use_tree
|
// test use_tree
|
||||||
// use outer::tree::{inner::tree};
|
// use outer::tree::{inner::tree};
|
||||||
fn use_tree(p: &mut Parser<'_>, top_level: bool) {
|
fn use_tree(p: &mut Parser<'_>, top_level: bool) -> bool {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
match p.current() {
|
match p.current() {
|
||||||
// test use_tree_star
|
// test use_tree_star
|
||||||
|
@ -70,24 +70,32 @@ fn use_tree(p: &mut Parser<'_>, top_level: bool) {
|
||||||
// main balanced `{}`
|
// main balanced `{}`
|
||||||
p.err_and_bump(msg);
|
p.err_and_bump(msg);
|
||||||
}
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.complete(p, USE_TREE);
|
m.complete(p, USE_TREE);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) const USE_TREE_LIST_RECOVERY_SET: TokenSet =
|
||||||
|
TokenSet::new(&[T![;], T![,], T![.], T![ident]]).union(ITEM_RECOVERY_SET);
|
||||||
|
|
||||||
|
pub(super) const USE_TREE_LIST_FIRST_SET: TokenSet = TokenSet::new(&[T!['{'], T![ident]]);
|
||||||
|
|
||||||
// test use_tree_list
|
// test use_tree_list
|
||||||
// use {a, b, c};
|
// use {a, b, c};
|
||||||
pub(crate) fn use_tree_list(p: &mut Parser<'_>) {
|
pub(crate) fn use_tree_list(p: &mut Parser<'_>) {
|
||||||
assert!(p.at(T!['{']));
|
assert!(p.at(T!['{']));
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump(T!['{']);
|
|
||||||
while !p.at(EOF) && !p.at(T!['}']) {
|
// test_err use_tree_list_err_recovery
|
||||||
use_tree(p, false);
|
// use {a;
|
||||||
if !p.at(T!['}']) {
|
// use b;
|
||||||
p.expect(T![,]);
|
// struct T;
|
||||||
}
|
// fn test() {}
|
||||||
}
|
delimited(p, T!['{'], T!['}'], T![,], USE_TREE_LIST_FIRST_SET, |p: &mut Parser<'_>| {
|
||||||
p.expect(T!['}']);
|
use_tree(p, false) || p.at_ts(USE_TREE_LIST_RECOVERY_SET)
|
||||||
|
});
|
||||||
|
|
||||||
m.complete(p, USE_TREE_LIST);
|
m.complete(p, USE_TREE_LIST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,9 @@ SOURCE_FILE
|
||||||
PATH_SEGMENT
|
PATH_SEGMENT
|
||||||
NAME_REF
|
NAME_REF
|
||||||
IDENT "Error"
|
IDENT "Error"
|
||||||
ERROR
|
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
ERROR
|
USE
|
||||||
USE_KW "use"
|
USE_KW "use"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
USE_TREE
|
USE_TREE
|
||||||
|
@ -36,16 +35,6 @@ SOURCE_FILE
|
||||||
PATH_SEGMENT
|
PATH_SEGMENT
|
||||||
NAME_REF
|
NAME_REF
|
||||||
IDENT "io"
|
IDENT "io"
|
||||||
ERROR
|
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
error 22: expected COMMA
|
error 22: expected R_CURLY
|
||||||
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 SEMICOLON
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
SOURCE_FILE
|
||||||
|
USE
|
||||||
|
USE_KW "use"
|
||||||
|
WHITESPACE " "
|
||||||
|
USE_TREE
|
||||||
|
USE_TREE_LIST
|
||||||
|
L_CURLY "{"
|
||||||
|
USE_TREE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "a"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
USE
|
||||||
|
USE_KW "use"
|
||||||
|
WHITESPACE " "
|
||||||
|
USE_TREE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "b"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
STRUCT
|
||||||
|
STRUCT_KW "struct"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "T"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
FN
|
||||||
|
FN_KW "fn"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "test"
|
||||||
|
PARAM_LIST
|
||||||
|
L_PAREN "("
|
||||||
|
R_PAREN ")"
|
||||||
|
WHITESPACE " "
|
||||||
|
BLOCK_EXPR
|
||||||
|
STMT_LIST
|
||||||
|
L_CURLY "{"
|
||||||
|
R_CURLY "}"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
error 6: expected R_CURLY
|
|
@ -0,0 +1,4 @@
|
||||||
|
use {a;
|
||||||
|
use b;
|
||||||
|
struct T;
|
||||||
|
fn test() {}
|
Loading…
Add table
Add a link
Reference in a new issue