diff options
author | Aleksey Kladov <[email protected]> | 2019-06-08 18:42:02 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-06-08 18:42:02 +0100 |
commit | caefa6982bc57195687de11137997f1d62d791fe (patch) | |
tree | 4cdbfe1ae67d0eae6ba85b19cf40126898f43ac5 /crates/ra_hir/src/nameres/collector.rs | |
parent | 780e1a365b10027c4bd4adcc939ab32da1d91492 (diff) |
remove some hacks from nameresolution for macros
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 38 |
1 files changed, 28 insertions, 10 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 | }; |