aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorDJMcNab <[email protected]>2018-12-21 22:29:59 +0000
committerDJMcNab <[email protected]>2018-12-21 22:29:59 +0000
commitd8d60215dacc3eeddeda4d6af7007e2129fdb00e (patch)
tree4caab03638e2a66c06f91d21762b09bab5cdca4a /crates/ra_hir
parent67ac0a423f767ce8973348d5188e8baa6979d380 (diff)
Fix handling of nested self in paths
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/module/nameres/tests.rs19
-rw-r--r--crates/ra_hir/src/path.rs22
2 files changed, 39 insertions, 2 deletions
diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs
index 9fa9146e3..3e29c3954 100644
--- a/crates/ra_hir/src/module/nameres/tests.rs
+++ b/crates/ra_hir/src/module/nameres/tests.rs
@@ -44,6 +44,25 @@ fn item_map_smoke_test() {
44} 44}
45 45
46#[test] 46#[test]
47fn test_self() {
48 let (item_map, module_id) = item_map(
49 "
50 //- /lib.rs
51 mod foo;
52 use crate::foo::bar::Baz::{self};
53 <|>
54 //- /foo/mod.rs
55 pub mod bar;
56 //- /foo/bar.rs
57 pub struct Baz;
58 ",
59 );
60 let name = SmolStr::from("Baz");
61 let resolution = &item_map.per_module[&module_id].items[&name];
62 assert!(resolution.def_id.is_some());
63}
64
65#[test]
47fn item_map_across_crates() { 66fn item_map_across_crates() {
48 let (mut db, sr) = MockDatabase::with_files( 67 let (mut db, sr) = MockDatabase::with_files(
49 " 68 "
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 4a2e427cd..1b3fb4306 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -76,14 +76,32 @@ fn expand_use_tree(
76) { 76) {
77 if let Some(use_tree_list) = tree.use_tree_list() { 77 if let Some(use_tree_list) = tree.use_tree_list() {
78 let prefix = match tree.path() { 78 let prefix = match tree.path() {
79 // E.g. use something::{{{inner}}};
79 None => prefix, 80 None => prefix,
81 // E.g. `use something::{inner}` (prefix is `None`, path is `something`)
82 // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
80 Some(path) => match convert_path(prefix, path) { 83 Some(path) => match convert_path(prefix, path) {
81 Some(it) => Some(it), 84 Some(it) => Some(it),
82 None => return, // TODO: report errors somewhere 85 None => return, // TODO: report errors somewhere
83 }, 86 },
84 }; 87 };
85 for tree in use_tree_list.use_trees() { 88 for child_tree in use_tree_list.use_trees() {
86 expand_use_tree(prefix.clone(), tree, cb); 89 // Handle self in a path.
90 // E.g. `use something::{self, <...>}`
91 if let Some(path) = child_tree.path() {
92 if path.qualifier().is_none() {
93 if let Some(segment) = path.segment() {
94 if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
95 /* TODO: Work out what on earth range means in this callback */
96 if let Some(prefix) = prefix.clone() {
97 cb(prefix, Some(segment.syntax().range()));
98 continue;
99 }
100 }
101 }
102 }
103 }
104 expand_use_tree(prefix.clone(), child_tree, cb);
87 } 105 }
88 } else { 106 } else {
89 if let Some(ast_path) = tree.path() { 107 if let Some(ast_path) = tree.path() {