diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index cbfeca3abb..287cea8808 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -14,7 +14,8 @@ use hir_def::{ DefWithBodyId, }; use hir_expand::{ - name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, + hygiene::Hygiene, name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, + Source, }; use ra_syntax::{ ast::{self, AstNode}, @@ -236,10 +237,10 @@ impl SourceAnalyzer { pub fn resolve_macro_call( &self, db: &impl HirDatabase, - macro_call: &ast::MacroCall, + macro_call: Source<&ast::MacroCall>, ) -> Option { - // This must be a normal source file rather than macro file. - let path = macro_call.path().and_then(Path::from_ast)?; + let hygiene = Hygiene::new(db, macro_call.file_id); + let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) } @@ -441,12 +442,14 @@ impl SourceAnalyzer { db: &impl HirDatabase, macro_call: Source<&ast::MacroCall>, ) -> Option { - let def = self.resolve_macro_call(db, macro_call.value)?.id; + let def = self.resolve_macro_call(db, macro_call)?.id; let ast_id = AstId::new( macro_call.file_id, db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), ); let macro_call_loc = MacroCallLoc { def, ast_id }; + let kind = to_macro_file_kind(macro_call.value); + dbg!(kind); Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc), macro_file_kind: to_macro_file_kind(macro_call.value), diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 0e606fd0e8..6810a26dbb 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -97,7 +97,7 @@ impl Path { /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub(crate) fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { + pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { let mut kind = PathKind::Plain; let mut segments = Vec::new(); loop { diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 9beceb29cf..7ebdfc585a 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -18,12 +18,9 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { //FIXME: don't poke into Ty @@ -44,7 +41,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { - let macro_def = analyzer.resolve_macro_call(db, &expr)?; + let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?; (CallInfo::with_macro(db, macro_def)?, false) } }; diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 0b540b8cde..abc602244c 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -269,4 +269,27 @@ fn some_thing() -> u32 { assert_eq!(res.name, "foo"); assert_snapshot!(res.expansion, @r###"bar!()"###); } + + #[test] + fn macro_expand_with_dollar_crate() { + let res = check_expand_macro( + r#" + //- /lib.rs + #[macro_export] + macro_rules! bar { + () => {0}; + } + macro_rules! foo { + () => {$crate::bar!()}; + } + + fn main() { + let res = fo<|>o!(); + } + "#, + ); + + assert_eq!(res.name, "foo"); + assert_snapshot!(res.expansion, @r###"0"###); + } } diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index cab06dea94..227737ad24 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs @@ -152,7 +152,7 @@ pub(crate) fn classify_name_ref( if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { tested_by!(goto_definition_works_for_macros); - if let Some(macro_def) = analyzer.resolve_macro_call(db, ¯o_call) { + if let Some(macro_def) = analyzer.resolve_macro_call(db, name_ref.with_value(¯o_call)) { let kind = NameKind::Macro(macro_def); return Some(NameDefinition { kind, container, visibility }); }