diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index d6c7c083d..5af26f953 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -183,11 +183,14 @@ where | |||
183 | 183 | ||
184 | if let Some(ModuleDef::Module(m)) = res.take_types() { | 184 | if let Some(ModuleDef::Module(m)) = res.take_types() { |
185 | tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); | 185 | tested_by!(macro_rules_from_other_crates_are_visible_with_macro_use); |
186 | self.import_all_macros_exported(m); | ||
187 | } | ||
188 | } | ||
186 | 189 | ||
187 | let item_map = self.db.crate_def_map(m.krate); | 190 | fn import_all_macros_exported(&mut self, module: Module) { |
188 | for (name, ¯o_id) in &item_map.exported_macros { | 191 | let item_map = self.db.crate_def_map(module.krate); |
189 | self.global_macro_scope.insert(name.clone(), macro_id); | 192 | for (name, ¯o_id) in &item_map.exported_macros { |
190 | } | 193 | self.global_macro_scope.insert(name.clone(), macro_id); |
191 | } | 194 | } |
192 | } | 195 | } |
193 | 196 | ||
@@ -520,20 +523,32 @@ where | |||
520 | DB: DefDatabase, | 523 | DB: DefDatabase, |
521 | { | 524 | { |
522 | fn collect(&mut self, items: &[raw::RawItem]) { | 525 | fn collect(&mut self, items: &[raw::RawItem]) { |
526 | // Prelude module is always considered to be `#[macro_use]`. | ||
527 | if let Some(prelude_module) = self.def_collector.def_map.prelude { | ||
528 | tested_by!(prelude_is_macro_use); | ||
529 | self.def_collector.import_all_macros_exported(prelude_module); | ||
530 | } | ||
531 | |||
532 | // This should be processed eagerly instead of deferred to resolving. | ||
533 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | ||
534 | // any other items. | ||
535 | for item in items { | ||
536 | if let raw::RawItem::Import(import_id) = *item { | ||
537 | let import = self.raw_items[import_id].clone(); | ||
538 | if import.is_extern_crate && import.is_macro_use { | ||
539 | self.def_collector.import_macros_from_extern_crate(&import); | ||
540 | } | ||
541 | } | ||
542 | } | ||
543 | |||
523 | for item in items { | 544 | for item in items { |
524 | match *item { | 545 | match *item { |
525 | raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]), | 546 | raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]), |
526 | raw::RawItem::Import(import_id) => { | 547 | raw::RawItem::Import(import_id) => self.def_collector.unresolved_imports.push(( |
527 | let import = self.raw_items[import_id].clone(); | 548 | self.module_id, |
528 | // This should be processed eagerly instead of deferred to resolving. | 549 | import_id, |
529 | // Otherwise, since it will only mutate `global_macro_scope` | 550 | self.raw_items[import_id].clone(), |
530 | // without `update` names in `mod`s, unresolved macros cannot be expanded. | 551 | )), |
531 | if import.is_extern_crate && import.is_macro_use { | ||
532 | self.def_collector.import_macros_from_extern_crate(&import); | ||
533 | } | ||
534 | |||
535 | self.def_collector.unresolved_imports.push((self.module_id, import_id, import)); | ||
536 | } | ||
537 | raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]), | 552 | raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]), |
538 | raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]), | 553 | raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]), |
539 | } | 554 | } |