aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r--crates/ra_hir/src/nameres/collector.rs38
-rw-r--r--crates/ra_hir/src/nameres/tests/macros.rs13
2 files changed, 37 insertions, 14 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 3bfef799d..99110d58d 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -138,15 +138,35 @@ where
138 } 138 }
139 } 139 }
140 140
141 fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { 141 fn define_macro(
142 &mut self,
143 module_id: CrateModuleId,
144 name: Name,
145 macro_id: MacroDefId,
146 export: bool,
147 ) {
148 // macro-by-example in Rust have completely weird name resolution logic,
149 // unlike anything else in the language. We'd don't fully implement yet,
150 // just give a somewhat precise approximation.
151 //
152 // Specifically, we store a set of visible macros in each module, just
153 // like how we do with usual items. This is wrong, however, because
154 // macros can be shadowed and their scopes are mostly unrelated to
155 // modules. To paper over the second problem, we also maintain
156 // `global_macro_scope` which works when we construct `CrateDefMap`, but
157 // is completely ignored in expressions.
158 //
159 // What we should do is that, in CrateDefMap, we should maintain a
160 // separate tower of macro scopes, with ids. Then, for each item in the
161 // module, we need to store it's macro scope.
162 let def = Either::Right(MacroDef { id: macro_id });
163
164 // In Rust, `#[macro_export]` macros are unconditionally visible at the
165 // crate root, even if the parent modules is **not** visible.
142 if export { 166 if export {
143 self.def_map.public_macros.insert(name.clone(), macro_id); 167 self.update(self.def_map.root, None, &[(name.clone(), def.clone())]);
144
145 let def = Either::Right(MacroDef { id: macro_id });
146 self.update(self.def_map.root, None, &[(name.clone(), def)]);
147 } else {
148 self.def_map.local_macros.insert(name.clone(), macro_id);
149 } 168 }
169 self.update(module_id, None, &[(name.clone(), def)]);
150 self.global_macro_scope.insert(name, macro_id); 170 self.global_macro_scope.insert(name, macro_id);
151 } 171 }
152 172
@@ -589,7 +609,7 @@ where
589 if is_macro_rules(&mac.path) { 609 if is_macro_rules(&mac.path) {
590 if let Some(name) = &mac.name { 610 if let Some(name) = &mac.name {
591 let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id)); 611 let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id));
592 self.def_collector.define_macro(name.clone(), macro_id, mac.export) 612 self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export)
593 } 613 }
594 return; 614 return;
595 } 615 }
@@ -694,9 +714,7 @@ mod tests {
694 prelude: None, 714 prelude: None,
695 root, 715 root,
696 modules, 716 modules,
697 public_macros: FxHashMap::default(),
698 poison_macros: FxHashSet::default(), 717 poison_macros: FxHashSet::default(),
699 local_macros: FxHashMap::default(),
700 diagnostics: Vec::new(), 718 diagnostics: Vec::new(),
701 } 719 }
702 }; 720 };
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs
index 42241aeff..4e04740eb 100644
--- a/crates/ra_hir/src/nameres/tests/macros.rs
+++ b/crates/ra_hir/src/nameres/tests/macros.rs
@@ -21,6 +21,7 @@ fn macro_rules_are_globally_visible() {
21 ⋮crate 21 ⋮crate
22 ⋮Foo: t v 22 ⋮Foo: t v
23 ⋮nested: t 23 ⋮nested: t
24 ⋮structs: m
24 25
25 ⋮crate::nested 26 ⋮crate::nested
26 ⋮Bar: t v 27 ⋮Bar: t v
@@ -46,6 +47,7 @@ fn macro_rules_can_define_modules() {
46 ); 47 );
47 assert_snapshot_matches!(map, @r###" 48 assert_snapshot_matches!(map, @r###"
48 ⋮crate 49 ⋮crate
50 ⋮m: m
49 ⋮n1: t 51 ⋮n1: t
50 52
51 ⋮crate::n1 53 ⋮crate::n1
@@ -127,8 +129,11 @@ fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
127 "foo": ("/lib.rs", []), 129 "foo": ("/lib.rs", []),
128 }, 130 },
129 ); 131 );
130 assert_snapshot_matches!(map, @r###"crate 132 assert_snapshot_matches!(map, @r###"
131Foo: t v 133 ⋮crate
132bar: m 134 ⋮Foo: t v
133foo: m"###); 135 ⋮bar: m
136 ⋮baz: m
137 ⋮foo: m
138 "###);
134} 139}