diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index f575d738feb3..c30b2061158d 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs @@ -866,4 +866,22 @@ type Alias = T<|>; "#, ) } + + #[test] + fn goto_def_for_macro_container() { + check( + r#" +//- /lib.rs +foo::module<|>::mac!(); + +//- /foo/lib.rs +pub mod module { + //^^^^^^ + #[macro_export] + macro_rules! _mac { () => { () } } + pub use crate::_mac as mac; +} +"#, + ); + } } diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs index 3ef5e74b6997..bcaabca92f10 100644 --- a/crates/ra_ide_db/src/defs.rs +++ b/crates/ra_ide_db/src/defs.rs @@ -255,8 +255,14 @@ pub fn classify_name_ref( } if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { - if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { - return Some(NameRefClass::Definition(Definition::Macro(macro_def))); + if let Some(path) = macro_call.path() { + if path.qualifier().is_none() { + // Only use this to resolve single-segment macro calls like `foo!()`. Multi-segment + // paths are handled below (allowing `log<|>::info!` to resolve to the log crate). + if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { + return Some(NameRefClass::Definition(Definition::Macro(macro_def))); + } + } } }