Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-completion/src/tests/use_tree.rs27
-rw-r--r--crates/parser/src/grammar/items/use_item.rs28
-rw-r--r--crates/parser/test_data/parser/err/0036_partial_use.rast45
-rw-r--r--crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast46
-rw-r--r--crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs4
5 files changed, 112 insertions, 38 deletions
diff --git a/crates/ide-completion/src/tests/use_tree.rs b/crates/ide-completion/src/tests/use_tree.rs
index 167bdec546..f8b76571ca 100644
--- a/crates/ide-completion/src/tests/use_tree.rs
+++ b/crates/ide-completion/src/tests/use_tree.rs
@@ -9,6 +9,33 @@ fn check(ra_fixture: &str, expect: Expect) {
}
#[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]
fn use_tree_start() {
cov_mark::check!(unqualified_path_selected_only);
check(
diff --git a/crates/parser/src/grammar/items/use_item.rs b/crates/parser/src/grammar/items/use_item.rs
index 69880b7946..f689c06b31 100644
--- a/crates/parser/src/grammar/items/use_item.rs
+++ b/crates/parser/src/grammar/items/use_item.rs
@@ -11,7 +11,7 @@ pub(super) fn use_(p: &mut Parser<'_>, m: Marker) {
// test use_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();
match p.current() {
// test use_tree_star
@@ -70,24 +70,32 @@ fn use_tree(p: &mut Parser<'_>, top_level: bool) {
// main balanced `{}`
p.err_and_bump(msg);
}
- return;
+ return false;
}
}
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
// use {a, b, c};
pub(crate) fn use_tree_list(p: &mut Parser<'_>) {
assert!(p.at(T!['{']));
let m = p.start();
- p.bump(T!['{']);
- while !p.at(EOF) && !p.at(T!['}']) {
- use_tree(p, false);
- if !p.at(T!['}']) {
- p.expect(T![,]);
- }
- }
- p.expect(T!['}']);
+
+ // test_err use_tree_list_err_recovery
+ // use {a;
+ // use b;
+ // struct T;
+ // fn test() {}
+ delimited(p, T!['{'], T!['}'], T![,], USE_TREE_LIST_FIRST_SET, |p: &mut Parser<'_>| {
+ use_tree(p, false) || p.at_ts(USE_TREE_LIST_RECOVERY_SET)
+ });
+
m.complete(p, USE_TREE_LIST);
}
diff --git a/crates/parser/test_data/parser/err/0036_partial_use.rast b/crates/parser/test_data/parser/err/0036_partial_use.rast
index 13e76e6830..e27c941793 100644
--- a/crates/parser/test_data/parser/err/0036_partial_use.rast
+++ b/crates/parser/test_data/parser/err/0036_partial_use.rast
@@ -20,32 +20,21 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Error"
- ERROR
- SEMICOLON ";"
- WHITESPACE "\n"
- ERROR
- USE_KW "use"
- WHITESPACE " "
- USE_TREE
- PATH
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "std"
- COLON2 "::"
- PATH_SEGMENT
- NAME_REF
- IDENT "io"
- ERROR
- SEMICOLON ";"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ USE
+ USE_KW "use"
+ WHITESPACE " "
+ USE_TREE
+ PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "std"
+ COLON2 "::"
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "io"
+ SEMICOLON ";"
WHITESPACE "\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 SEMICOLON
+error 22: expected R_CURLY
diff --git a/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast b/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast
new file mode 100644
index 0000000000..cb90b093ba
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rast
@@ -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
diff --git a/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs b/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs
new file mode 100644
index 0000000000..f16959c25f
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0026_use_tree_list_err_recovery.rs
@@ -0,0 +1,4 @@
+use {a;
+use b;
+struct T;
+fn test() {}