diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs index 9fa9146e3c..3e29c39541 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs @@ -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( diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 4a2e427cd9..e04d00900a 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs @@ -76,17 +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() { + expand_use_tree(prefix.clone(), child_tree, cb); } } else { if let Some(ast_path) = tree.path() { + // Handle self in a path. + // E.g. `use something::{self, <...>}` + if ast_path.qualifier().is_none() { + if let Some(segment) = ast_path.segment() { + if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { + if let Some(prefix) = prefix { + cb(prefix, Some(segment.syntax().range())); + return; + } + } + } + } if let Some(path) = convert_path(prefix, ast_path) { let range = if tree.has_star() { None @@ -96,6 +111,8 @@ fn expand_use_tree( }; cb(path, range) } + // TODO: report errors somewhere + // We get here if we do } } } diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 91c67119fb..f12479fb46 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -284,7 +284,7 @@ impl<'a> IfExpr<'a> { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PathSegmentKind<'a> { Name(NameRef<'a>), SelfKw,