aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs5
-rw-r--r--crates/ide/src/references.rs30
-rw-r--r--crates/ide_db/src/search.rs25
3 files changed, 56 insertions, 4 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 68f4551c0..ea0a60961 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1150,6 +1150,11 @@ impl MacroDef {
1150 // FIXME: wrong for `ProcMacro` 1150 // FIXME: wrong for `ProcMacro`
1151 matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..)) 1151 matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..))
1152 } 1152 }
1153
1154 /// Indicate it is a declarative macro
1155 pub fn is_declarative(&self) -> bool {
1156 matches!(self.id.kind, MacroDefKind::Declarative(..))
1157 }
1153} 1158}
1154 1159
1155/// Invariant: `inner.as_assoc_item(db).is_some()` 1160/// Invariant: `inner.as_assoc_item(db).is_some()`
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 379674530..95ed8a045 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -1294,4 +1294,34 @@ pub use level1::Foo;
1294 "#]], 1294 "#]],
1295 ); 1295 );
1296 } 1296 }
1297
1298 #[test]
1299 fn test_decl_macro_references() {
1300 check(
1301 r#"
1302//- /lib.rs crate:lib
1303#[macro_use]
1304mod qux;
1305mod bar;
1306
1307pub use self::foo;
1308//- /qux.rs
1309#[macro_export]
1310macro_rules! foo$0 {
1311 () => {struct Foo;};
1312}
1313//- /bar.rs
1314foo!();
1315//- /other.rs crate:other deps:lib new_source_root:
1316lib::foo!();
1317"#,
1318 expect![[r#"
1319 foo Macro FileId(1) 0..61 29..32
1320
1321 FileId(0) 46..49
1322 FileId(2) 0..3
1323 FileId(3) 5..8
1324 "#]],
1325 );
1326 }
1297} 1327}
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs
index 8e93de277..5fdcb13cf 100644
--- a/crates/ide_db/src/search.rs
+++ b/crates/ide_db/src/search.rs
@@ -7,7 +7,7 @@
7use std::{convert::TryInto, mem}; 7use std::{convert::TryInto, mem};
8 8
9use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt}; 9use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
10use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; 10use hir::{DefWithBody, HasAttrs, HasSource, Module, ModuleSource, Semantics, Visibility};
11use once_cell::unsync::Lazy; 11use once_cell::unsync::Lazy;
12use rustc_hash::FxHashMap; 12use rustc_hash::FxHashMap;
13use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; 13use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
@@ -244,9 +244,8 @@ impl Definition {
244 return SearchScope::new(res); 244 return SearchScope::new(res);
245 } 245 }
246 246
247 if let Some(Visibility::Public) = vis { 247 let rev_dep_scope = || {
248 let mut res = FxHashMap::default(); 248 let mut res = FxHashMap::default();
249
250 let krate = module.krate(); 249 let krate = module.krate();
251 for rev_dep in krate.transitive_reverse_dependencies(db) { 250 for rev_dep in krate.transitive_reverse_dependencies(db) {
252 let root_file = rev_dep.root_file(db); 251 let root_file = rev_dep.root_file(db);
@@ -254,7 +253,25 @@ impl Definition {
254 let source_root = db.source_root(source_root_id); 253 let source_root = db.source_root(source_root_id);
255 res.extend(source_root.iter().map(|id| (id, None))); 254 res.extend(source_root.iter().map(|id| (id, None)));
256 } 255 }
257 return SearchScope::new(res); 256 SearchScope::new(res)
257 };
258
259 if let Definition::Macro(macro_def) = self {
260 if macro_def.is_declarative() {
261 return if macro_def.attrs(db).by_key("macro_export").exists() {
262 rev_dep_scope()
263 } else {
264 let source_root_id = db.file_source_root(file_id);
265 let source_root = db.source_root(source_root_id);
266 SearchScope::new(
267 source_root.iter().map(|id| (id, None)).collect::<FxHashMap<_, _>>(),
268 )
269 };
270 }
271 }
272
273 if let Some(Visibility::Public) = vis {
274 return rev_dep_scope();
258 } 275 }
259 276
260 let mut res = FxHashMap::default(); 277 let mut res = FxHashMap::default();