aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/grammar/items
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/grammar/items')
-rw-r--r--crates/ra_syntax/src/grammar/items/use_item.rs55
1 files changed, 54 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/grammar/items/use_item.rs b/crates/ra_syntax/src/grammar/items/use_item.rs
index 1ee4349fd..b3c78f351 100644
--- a/crates/ra_syntax/src/grammar/items/use_item.rs
+++ b/crates/ra_syntax/src/grammar/items/use_item.rs
@@ -7,25 +7,75 @@ pub(super) fn use_item(p: &mut Parser) {
7 p.expect(SEMI); 7 p.expect(SEMI);
8} 8}
9 9
10/// Parse a use 'tree', such as `some::path` in `use some::path;`
11/// Note that this is called both by `use_item` and `use_tree_list`,
12/// so handles both `some::path::{inner::path}` and `inner::path` in
13/// `use some::path::{inner::path};`
10fn use_tree(p: &mut Parser) { 14fn use_tree(p: &mut Parser) {
11 let la = p.nth(1); 15 let la = p.nth(1);
12 let m = p.start(); 16 let m = p.start();
13 match (p.current(), la) { 17 match (p.current(), la) {
18 // Finish the use_tree for cases of e.g.
19 // `use some::path::{self, *};` or `use *;`
20 // This does not handle cases such as `use some::path::*`
21 // N.B. in Rust 2015 `use *;` imports all from crate root
22 // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
23 // TODO: Add this error (if not out of scope)
24
25 // test use_star
26 // use *;
27 // use ::*;
28 // use some::path::{*};
29 // use some::path::{::*};
14 (STAR, _) => p.bump(), 30 (STAR, _) => p.bump(),
15 (COLONCOLON, STAR) => { 31 (COLONCOLON, STAR) => {
32 // Parse `use ::*;`, which imports all from the crate root in Rust 2015
33 // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
34 // but still parses and errors later: ('crate root in paths can only be used in start position')
35 // TODO: Add this error (if not out of scope)
36 // In Rust 2018, it is always invalid (see above)
16 p.bump(); 37 p.bump();
17 p.bump(); 38 p.bump();
18 } 39 }
40 // Open a use tree list
41 // Handles cases such as `use {some::path};` or `{inner::path}` in
42 // `use some::path::{{inner::path}, other::path}`
43
44 // test use_tree_list
45 // use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`)
46 // use {path::from::root}; // Rust 2015
47 // use ::{some::arbritrary::path}; // Rust 2015
48 // use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig
19 (L_CURLY, _) | (COLONCOLON, L_CURLY) => { 49 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
20 if p.at(COLONCOLON) { 50 if p.at(COLONCOLON) {
21 p.bump(); 51 p.bump();
22 } 52 }
23 use_tree_list(p); 53 use_tree_list(p);
24 } 54 }
55 // Parse a 'standard' path.
56 // Also handles aliases (e.g. `use something as something_else`)
57
58 // test use_path
59 // use ::crate_name; // Rust 2018 - All flavours
60 // use crate_name; // Rust 2018 - Anchored paths
61 // use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths
62 //
63 // use self::module::Item;
64 // use crate::Item;
65 // use self::some::Struct;
66 // use crate_name::some_item;
25 _ if paths::is_path_start(p) => { 67 _ if paths::is_path_start(p) => {
26 paths::use_path(p); 68 paths::use_path(p);
27 match p.current() { 69 match p.current() {
28 AS_KW => { 70 AS_KW => {
71 // test use_alias
72 // use some::path as some_name;
73 // use some::{
74 // other::path as some_other_name,
75 // different::path as different_name,
76 // yet::another::path,
77 // running::out::of::synonyms::for::different::*
78 // };
29 opt_alias(p); 79 opt_alias(p);
30 } 80 }
31 COLONCOLON => { 81 COLONCOLON => {
@@ -34,6 +84,9 @@ fn use_tree(p: &mut Parser) {
34 STAR => { 84 STAR => {
35 p.bump(); 85 p.bump();
36 } 86 }
87 // test use_tree_list_after_path
88 // use crate::{Item};
89 // use self::{Item};
37 L_CURLY => use_tree_list(p), 90 L_CURLY => use_tree_list(p),
38 _ => { 91 _ => {
39 // is this unreachable? 92 // is this unreachable?
@@ -46,7 +99,7 @@ fn use_tree(p: &mut Parser) {
46 } 99 }
47 _ => { 100 _ => {
48 m.abandon(p); 101 m.abandon(p);
49 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); 102 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super` or an indentifier");
50 return; 103 return;
51 } 104 }
52 } 105 }