aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/nameres.rs27
-rw-r--r--crates/ra_hir/src/nameres/collector.rs37
-rw-r--r--crates/ra_hir/src/nameres/tests/macros.rs2
-rw-r--r--crates/ra_hir/src/ty/tests.rs2
4 files changed, 39 insertions, 29 deletions
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index befbb2a9b..74546e5e2 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -138,8 +138,21 @@ pub(crate) struct ModuleData {
138#[derive(Debug, Default, PartialEq, Eq, Clone)] 138#[derive(Debug, Default, PartialEq, Eq, Clone)]
139pub struct ModuleScope { 139pub struct ModuleScope {
140 items: FxHashMap<Name, Resolution>, 140 items: FxHashMap<Name, Resolution>,
141 /// Macros in current module scoped
142 ///
143 /// This scope works exactly the same way that item scoping does.
144 /// Macro invocation with quantified path will search in it.
145 /// See details below.
141 macros: FxHashMap<Name, MacroDef>, 146 macros: FxHashMap<Name, MacroDef>,
142 textual_macros: FxHashMap<Name, MacroDef>, 147 /// Macros visable in current module in legacy textual scope
148 ///
149 /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
150 /// If it yields no result, then it turns to module scoped `macros`.
151 /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
152 /// and only normal scoped `macros` will be searched in.
153 ///
154 /// Note that this automatically inherit macros defined textually before the definition of module itself.
155 legacy_macros: FxHashMap<Name, MacroDef>,
143} 156}
144 157
145static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| { 158static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
@@ -173,8 +186,8 @@ impl ModuleScope {
173 _ => None, 186 _ => None,
174 } 187 }
175 } 188 }
176 fn get_textual_macro(&self, name: &Name) -> Option<MacroDef> { 189 fn get_legacy_macro(&self, name: &Name) -> Option<MacroDef> {
177 self.textual_macros.get(name).copied() 190 self.legacy_macros.get(name).copied()
178 } 191 }
179} 192}
180 193
@@ -489,13 +502,13 @@ impl CrateDefMap {
489 name: &Name, 502 name: &Name,
490 ) -> ItemOrMacro { 503 ) -> ItemOrMacro {
491 // Resolve in: 504 // Resolve in:
492 // - textual scoped macros 505 // - legacy scope
493 // - current module / scope 506 // - current module / scope
494 // - extern prelude 507 // - extern prelude
495 // - std prelude 508 // - std prelude
496 let from_textual_mcro = self[module] 509 let from_legacy_macro = self[module]
497 .scope 510 .scope
498 .get_textual_macro(name) 511 .get_legacy_macro(name)
499 .map_or_else(|| Either::A(PerNs::none()), Either::B); 512 .map_or_else(|| Either::A(PerNs::none()), Either::B);
500 let from_scope = 513 let from_scope =
501 self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none())); 514 self[module].scope.get_item_or_macro(name).unwrap_or_else(|| Either::A(PerNs::none()));
@@ -503,7 +516,7 @@ impl CrateDefMap {
503 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 516 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
504 let from_prelude = self.resolve_in_prelude(db, name); 517 let from_prelude = self.resolve_in_prelude(db, name);
505 518
506 or(from_textual_mcro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude))) 519 or(from_legacy_macro, or(from_scope, or(Either::A(from_extern_prelude), from_prelude)))
507 } 520 }
508 521
509 fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> { 522 fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> {
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 10c32ffa1..09cda7656 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -146,22 +146,19 @@ where
146 self.def_map.exported_macros.insert(name.clone(), macro_id); 146 self.def_map.exported_macros.insert(name.clone(), macro_id);
147 } 147 }
148 self.update(module_id, None, &[(name.clone(), def)]); 148 self.update(module_id, None, &[(name.clone(), def)]);
149 self.define_textual_macro(module_id, name.clone(), macro_id); 149 self.define_legacy_macro(module_id, name.clone(), macro_id);
150 } 150 }
151 151
152 /// Define a macro in current textual scope. 152 /// Define a legacy textual scoped macro in module
153 /// 153 ///
154 /// We use a map `textual_macros` to store all textual macros visable per module. 154 /// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module.
155 /// It will clone all macros from parent textual scope, whose definition is prior to 155 /// It will clone all macros from parent legacy scope, whose definition is prior to
156 /// the definition of current module. 156 /// the definition of current module.
157 /// And also, `macro_use` on a module will import all textual macros visable inside to 157 /// And also, `macro_use` on a module will import all legacy macros visable inside to
158 /// current textual scope, with possible shadowing. 158 /// current legacy scope, with possible shadowing.
159 fn define_textual_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) { 159 fn define_legacy_macro(&mut self, module_id: CrateModuleId, name: Name, macro_id: MacroDefId) {
160 // Always shadowing 160 // Always shadowing
161 self.def_map.modules[module_id] 161 self.def_map.modules[module_id].scope.legacy_macros.insert(name, MacroDef { id: macro_id });
162 .scope
163 .textual_macros
164 .insert(name, MacroDef { id: macro_id });
165 } 162 }
166 163
167 /// Import macros from `#[macro_use] extern crate`. 164 /// Import macros from `#[macro_use] extern crate`.
@@ -194,7 +191,7 @@ where
194 fn import_all_macros_exported(&mut self, current_module_id: CrateModuleId, module: Module) { 191 fn import_all_macros_exported(&mut self, current_module_id: CrateModuleId, module: Module) {
195 let item_map = self.db.crate_def_map(module.krate); 192 let item_map = self.db.crate_def_map(module.krate);
196 for (name, &macro_id) in &item_map.exported_macros { 193 for (name, &macro_id) in &item_map.exported_macros {
197 self.define_textual_macro(current_module_id, name.clone(), macro_id); 194 self.define_legacy_macro(current_module_id, name.clone(), macro_id);
198 } 195 }
199 } 196 }
200 197
@@ -578,7 +575,7 @@ where
578 } 575 }
579 .collect(&*items); 576 .collect(&*items);
580 if *is_macro_use { 577 if *is_macro_use {
581 self.import_all_textual_macros(module_id); 578 self.import_all_legacy_macros(module_id);
582 } 579 }
583 } 580 }
584 // out of line module, resolve, parse and recurse 581 // out of line module, resolve, parse and recurse
@@ -605,7 +602,7 @@ where
605 } 602 }
606 .collect(raw_items.items()); 603 .collect(raw_items.items());
607 if *is_macro_use { 604 if *is_macro_use {
608 self.import_all_textual_macros(module_id); 605 self.import_all_legacy_macros(module_id);
609 } 606 }
610 } 607 }
611 Err(candidate) => self.def_collector.def_map.diagnostics.push( 608 Err(candidate) => self.def_collector.def_map.diagnostics.push(
@@ -631,7 +628,7 @@ where
631 modules[res].parent = Some(self.module_id); 628 modules[res].parent = Some(self.module_id);
632 modules[res].declaration = Some(declaration); 629 modules[res].declaration = Some(declaration);
633 modules[res].definition = definition; 630 modules[res].definition = definition;
634 modules[res].scope.textual_macros = modules[self.module_id].scope.textual_macros.clone(); 631 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone();
635 modules[self.module_id].children.insert(name.clone(), res); 632 modules[self.module_id].children.insert(name.clone(), res);
636 let resolution = Resolution { 633 let resolution = Resolution {
637 def: PerNs::types( 634 def: PerNs::types(
@@ -685,10 +682,10 @@ where
685 682
686 let ast_id = mac.ast_id.with_file_id(self.file_id); 683 let ast_id = mac.ast_id.with_file_id(self.file_id);
687 684
688 // Case 2: try to resolve in textual scope and expand macro_rules, triggering 685 // Case 2: try to resolve in legacy scope and expand macro_rules, triggering
689 // recursive item collection. 686 // recursive item collection.
690 if let Some(macro_def) = mac.path.as_ident().and_then(|name| { 687 if let Some(macro_def) = mac.path.as_ident().and_then(|name| {
691 self.def_collector.def_map[self.module_id].scope.get_textual_macro(&name) 688 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name)
692 }) { 689 }) {
693 let def = macro_def.id; 690 let def = macro_def.id;
694 let macro_call_id = MacroCallLoc { def, ast_id }.id(self.def_collector.db); 691 let macro_call_id = MacroCallLoc { def, ast_id }.id(self.def_collector.db);
@@ -706,10 +703,10 @@ where
706 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path)); 703 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path));
707 } 704 }
708 705
709 fn import_all_textual_macros(&mut self, module_id: CrateModuleId) { 706 fn import_all_legacy_macros(&mut self, module_id: CrateModuleId) {
710 let macros = self.def_collector.def_map[module_id].scope.textual_macros.clone(); 707 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone();
711 for (name, macro_) in macros { 708 for (name, macro_) in macros {
712 self.def_collector.define_textual_macro(self.module_id, name.clone(), macro_.id); 709 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_.id);
713 } 710 }
714 } 711 }
715} 712}
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs
index a894c6836..21fab53e9 100644
--- a/crates/ra_hir/src/nameres/tests/macros.rs
+++ b/crates/ra_hir/src/nameres/tests/macros.rs
@@ -279,7 +279,7 @@ fn prelude_cycle() {
279} 279}
280 280
281#[test] 281#[test]
282fn plain_macros_are_textual_scoped() { 282fn plain_macros_are_legacy_textual_scoped() {
283 let map = def_map( 283 let map = def_map(
284 r#" 284 r#"
285 //- /main.rs 285 //- /main.rs
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index f2d5b115e..25716fe8c 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2804,7 +2804,7 @@ fn main() {
2804} 2804}
2805 2805
2806#[test] 2806#[test]
2807fn infer_textual_scoped_macros_expanded() { 2807fn infer_legacy_textual_scoped_macros_expanded() {
2808 assert_snapshot!( 2808 assert_snapshot!(
2809 infer(r#" 2809 infer(r#"
2810struct Foo(Vec<i32>); 2810struct Foo(Vec<i32>);