]> git.lizzy.rs Git - rust.git/commitdiff
Fix handling of nested self in paths
authorDJMcNab <36049421+DJMcNab@users.noreply.github.com>
Fri, 21 Dec 2018 22:29:59 +0000 (22:29 +0000)
committerDJMcNab <36049421+DJMcNab@users.noreply.github.com>
Fri, 21 Dec 2018 22:29:59 +0000 (22:29 +0000)
crates/ra_hir/src/module/nameres/tests.rs
crates/ra_hir/src/path.rs
crates/ra_syntax/src/ast.rs

index 9fa9146e3c59b2859063f0dd6f25157fa1a24f69..3e29c39541ab489423786d8fb978f566b6aff8ce 100644 (file)
@@ -43,6 +43,25 @@ fn item_map_smoke_test() {
     assert!(resolution.def_id.is_some());
 }
 
+#[test]
+fn test_self() {
+    let (item_map, module_id) = item_map(
+        "
+            //- /lib.rs
+            mod foo;
+            use crate::foo::bar::Baz::{self};
+            <|>
+            //- /foo/mod.rs
+            pub mod bar;
+            //- /foo/bar.rs
+            pub struct Baz;
+        ",
+    );
+    let name = SmolStr::from("Baz");
+    let resolution = &item_map.per_module[&module_id].items[&name];
+    assert!(resolution.def_id.is_some());
+}
+
 #[test]
 fn item_map_across_crates() {
     let (mut db, sr) = MockDatabase::with_files(
index 4a2e427cd90b6a91eaee0c6fd2776189bf5651b4..1b3fb430688fe3361829c7a7781031e633d6c3a4 100644 (file)
@@ -76,14 +76,32 @@ fn expand_use_tree(
 ) {
     if let Some(use_tree_list) = tree.use_tree_list() {
         let prefix = match tree.path() {
+            // E.g. use something::{{{inner}}};
             None => prefix,
+            // E.g. `use something::{inner}` (prefix is `None`, path is `something`)
+            // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
             Some(path) => match convert_path(prefix, path) {
                 Some(it) => Some(it),
                 None => return, // TODO: report errors somewhere
             },
         };
-        for tree in use_tree_list.use_trees() {
-            expand_use_tree(prefix.clone(), tree, cb);
+        for child_tree in use_tree_list.use_trees() {
+            // Handle self in a path.
+            // E.g. `use something::{self, <...>}`
+            if let Some(path) = child_tree.path() {
+                if path.qualifier().is_none() {
+                    if let Some(segment) = path.segment() {
+                        if segment.kind() == Some(ast::PathSegmentKind::SelfKw) {
+                            /* TODO: Work out what on earth range means in this callback */
+                            if let Some(prefix) = prefix.clone() {
+                                cb(prefix, Some(segment.syntax().range()));
+                                continue;
+                            }
+                        }
+                    }
+                }
+            }
+            expand_use_tree(prefix.clone(), child_tree, cb);
         }
     } else {
         if let Some(ast_path) = tree.path() {
index 91c67119fb880f1732cb9be3c04804c854814cbd..f12479fb46e19658d96ad6984e1df2fae0dbc574 100644 (file)
@@ -284,7 +284,7 @@ fn blocks(self) -> AstChildren<'a, Block<'a>> {
     }
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum PathSegmentKind<'a> {
     Name(NameRef<'a>),
     SelfKw,