aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs121
1 files changed, 67 insertions, 54 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 9996a0807..9ed48c506 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -13,22 +13,23 @@ use hir_expand::{
13 builtin_macro::find_builtin_macro, 13 builtin_macro::find_builtin_macro,
14 name::{AsName, Name}, 14 name::{AsName, Name},
15 proc_macro::ProcMacroExpander, 15 proc_macro::ProcMacroExpander,
16 HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 16 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
17}; 17};
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use rustc_hash::{FxHashMap, FxHashSet}; 19use rustc_hash::{FxHashMap, FxHashSet};
20use syntax::ast; 20use syntax::ast;
21use test_utils::mark;
22use tt::{Leaf, TokenTree}; 21use tt::{Leaf, TokenTree};
23 22
24use crate::{ 23use crate::{
25 attr::Attrs, 24 attr::Attrs,
26 db::DefDatabase, 25 db::DefDatabase,
26 item_attr_as_call_id,
27 item_scope::{ImportType, PerNsGlobImports}, 27 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 28 item_tree::{
29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, 29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30 StructDefKind, 30 StructDefKind,
31 }, 31 },
32 macro_call_as_call_id,
32 nameres::{ 33 nameres::{
33 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 34 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
34 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode, 35 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode,
@@ -36,9 +37,9 @@ use crate::{
36 path::{ImportAlias, ModPath, PathKind}, 37 path::{ImportAlias, ModPath, PathKind},
37 per_ns::PerNs, 38 per_ns::PerNs,
38 visibility::{RawVisibility, Visibility}, 39 visibility::{RawVisibility, Visibility},
39 AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, 40 AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
40 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, 41 LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
41 TypeAliasLoc, UnionLoc, 42 UnresolvedMacro,
42}; 43};
43 44
44const GLOB_RECURSION_LIMIT: usize = 100; 45const GLOB_RECURSION_LIMIT: usize = 100;
@@ -460,7 +461,7 @@ impl DefCollector<'_> {
460 let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name); 461 let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name);
461 462
462 if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { 463 if let Some(ModuleDefId::ModuleId(m)) = res.take_types() {
463 mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); 464 cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use);
464 self.import_all_macros_exported(current_module_id, m.krate); 465 self.import_all_macros_exported(current_module_id, m.krate);
465 } 466 }
466 } 467 }
@@ -569,10 +570,10 @@ impl DefCollector<'_> {
569 match def.take_types() { 570 match def.take_types() {
570 Some(ModuleDefId::ModuleId(m)) => { 571 Some(ModuleDefId::ModuleId(m)) => {
571 if import.is_prelude { 572 if import.is_prelude {
572 mark::hit!(std_prelude); 573 cov_mark::hit!(std_prelude);
573 self.def_map.prelude = Some(m); 574 self.def_map.prelude = Some(m);
574 } else if m.krate != self.def_map.krate { 575 } else if m.krate != self.def_map.krate {
575 mark::hit!(glob_across_crates); 576 cov_mark::hit!(glob_across_crates);
576 // glob import from other crate => we can just import everything once 577 // glob import from other crate => we can just import everything once
577 let item_map = m.def_map(self.db); 578 let item_map = m.def_map(self.db);
578 let scope = &item_map[m.local_id].scope; 579 let scope = &item_map[m.local_id].scope;
@@ -624,7 +625,7 @@ impl DefCollector<'_> {
624 } 625 }
625 } 626 }
626 Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => { 627 Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => {
627 mark::hit!(glob_enum); 628 cov_mark::hit!(glob_enum);
628 // glob import from enum => just import all the variants 629 // glob import from enum => just import all the variants
629 630
630 // XXX: urgh, so this works by accident! Here, we look at 631 // XXX: urgh, so this works by accident! Here, we look at
@@ -673,7 +674,7 @@ impl DefCollector<'_> {
673 674
674 self.update(module_id, &[(name, def)], vis, ImportType::Named); 675 self.update(module_id, &[(name, def)], vis, ImportType::Named);
675 } 676 }
676 None => mark::hit!(bogus_paths), 677 None => cov_mark::hit!(bogus_paths),
677 } 678 }
678 } 679 }
679 } 680 }
@@ -736,7 +737,7 @@ impl DefCollector<'_> {
736 if max_vis == old_vis { 737 if max_vis == old_vis {
737 false 738 false
738 } else { 739 } else {
739 mark::hit!(upgrade_underscore_visibility); 740 cov_mark::hit!(upgrade_underscore_visibility);
740 true 741 true
741 } 742 }
742 } 743 }
@@ -790,8 +791,11 @@ impl DefCollector<'_> {
790 return false; 791 return false;
791 } 792 }
792 793
793 if let Some(call_id) = 794 match macro_call_as_call_id(
794 directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { 795 &directive.ast_id,
796 self.db,
797 self.def_map.krate,
798 |path| {
795 let resolved_res = self.def_map.resolve_path_fp_with_macro( 799 let resolved_res = self.def_map.resolve_path_fp_with_macro(
796 self.db, 800 self.db,
797 ResolveMode::Other, 801 ResolveMode::Other,
@@ -800,24 +804,29 @@ impl DefCollector<'_> {
800 BuiltinShadowMode::Module, 804 BuiltinShadowMode::Module,
801 ); 805 );
802 resolved_res.resolved_def.take_macros() 806 resolved_res.resolved_def.take_macros()
803 }) 807 },
804 { 808 &mut |_err| (),
805 resolved.push((directive.module_id, call_id, directive.depth)); 809 ) {
806 res = ReachedFixedPoint::No; 810 Ok(Ok(call_id)) => {
807 return false; 811 resolved.push((directive.module_id, call_id, directive.depth));
812 res = ReachedFixedPoint::No;
813 return false;
814 }
815 Err(UnresolvedMacro) | Ok(Err(_)) => {}
808 } 816 }
809 817
810 true 818 true
811 }); 819 });
812 attribute_macros.retain(|directive| { 820 attribute_macros.retain(|directive| {
813 if let Some(call_id) = 821 match item_attr_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| {
814 directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { 822 self.resolve_attribute_macro(&directive, &path)
815 self.resolve_attribute_macro(&directive, &path) 823 }) {
816 }) 824 Ok(call_id) => {
817 { 825 resolved.push((directive.module_id, call_id, 0));
818 resolved.push((directive.module_id, call_id, 0)); 826 res = ReachedFixedPoint::No;
819 res = ReachedFixedPoint::No; 827 return false;
820 return false; 828 }
829 Err(UnresolvedMacro) => (),
821 } 830 }
822 831
823 true 832 true
@@ -856,7 +865,7 @@ impl DefCollector<'_> {
856 depth: usize, 865 depth: usize,
857 ) { 866 ) {
858 if depth > EXPANSION_DEPTH_LIMIT { 867 if depth > EXPANSION_DEPTH_LIMIT {
859 mark::hit!(macro_expansion_overflow); 868 cov_mark::hit!(macro_expansion_overflow);
860 log::warn!("macro expansion is too deep"); 869 log::warn!("macro expansion is too deep");
861 return; 870 return;
862 } 871 }
@@ -902,7 +911,8 @@ impl DefCollector<'_> {
902 911
903 for directive in &self.unexpanded_macros { 912 for directive in &self.unexpanded_macros {
904 let mut error = None; 913 let mut error = None;
905 directive.ast_id.as_call_id_with_errors( 914 match macro_call_as_call_id(
915 &directive.ast_id,
906 self.db, 916 self.db,
907 self.def_map.krate, 917 self.def_map.krate,
908 |path| { 918 |path| {
@@ -918,15 +928,15 @@ impl DefCollector<'_> {
918 &mut |e| { 928 &mut |e| {
919 error.get_or_insert(e); 929 error.get_or_insert(e);
920 }, 930 },
921 ); 931 ) {
922 932 Ok(_) => (),
923 if let Some(err) = error { 933 Err(UnresolvedMacro) => {
924 self.def_map.diagnostics.push(DefDiagnostic::macro_error( 934 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
925 directive.module_id, 935 directive.module_id,
926 MacroCallKind::FnLike(directive.ast_id.ast_id), 936 directive.ast_id.ast_id,
927 err.to_string(), 937 ));
928 )); 938 }
929 } 939 };
930 } 940 }
931 941
932 // Emit diagnostics for all remaining unresolved imports. 942 // Emit diagnostics for all remaining unresolved imports.
@@ -998,7 +1008,7 @@ impl ModCollector<'_, '_> {
998 // Prelude module is always considered to be `#[macro_use]`. 1008 // Prelude module is always considered to be `#[macro_use]`.
999 if let Some(prelude_module) = self.def_collector.def_map.prelude { 1009 if let Some(prelude_module) = self.def_collector.def_map.prelude {
1000 if prelude_module.krate != self.def_collector.def_map.krate { 1010 if prelude_module.krate != self.def_collector.def_map.krate {
1001 mark::hit!(prelude_is_macro_use); 1011 cov_mark::hit!(prelude_is_macro_use);
1002 self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate); 1012 self.def_collector.import_all_macros_exported(self.module_id, prelude_module.krate);
1003 } 1013 }
1004 } 1014 }
@@ -1032,7 +1042,6 @@ impl ModCollector<'_, '_> {
1032 } 1042 }
1033 } 1043 }
1034 let module = self.def_collector.def_map.module_id(self.module_id); 1044 let module = self.def_collector.def_map.module_id(self.module_id);
1035 let container = ContainerId::ModuleId(module);
1036 1045
1037 let mut def = None; 1046 let mut def = None;
1038 match item { 1047 match item {
@@ -1099,9 +1108,9 @@ impl ModCollector<'_, '_> {
1099 } 1108 }
1100 ModItem::Impl(imp) => { 1109 ModItem::Impl(imp) => {
1101 let module = self.def_collector.def_map.module_id(self.module_id); 1110 let module = self.def_collector.def_map.module_id(self.module_id);
1102 let container = ContainerId::ModuleId(module); 1111 let impl_id =
1103 let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } 1112 ImplLoc { container: module, id: ItemTreeId::new(self.file_id, imp) }
1104 .intern(self.def_collector.db); 1113 .intern(self.def_collector.db);
1105 self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id) 1114 self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
1106 } 1115 }
1107 ModItem::Function(id) => { 1116 ModItem::Function(id) => {
@@ -1111,7 +1120,7 @@ impl ModCollector<'_, '_> {
1111 1120
1112 def = Some(DefData { 1121 def = Some(DefData {
1113 id: FunctionLoc { 1122 id: FunctionLoc {
1114 container: container.into(), 1123 container: module.into(),
1115 id: ItemTreeId::new(self.file_id, id), 1124 id: ItemTreeId::new(self.file_id, id),
1116 } 1125 }
1117 .intern(self.def_collector.db) 1126 .intern(self.def_collector.db)
@@ -1130,7 +1139,7 @@ impl ModCollector<'_, '_> {
1130 self.collect_derives(&attrs, it.ast_id.upcast()); 1139 self.collect_derives(&attrs, it.ast_id.upcast());
1131 1140
1132 def = Some(DefData { 1141 def = Some(DefData {
1133 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } 1142 id: StructLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1134 .intern(self.def_collector.db) 1143 .intern(self.def_collector.db)
1135 .into(), 1144 .into(),
1136 name: &it.name, 1145 name: &it.name,
@@ -1147,7 +1156,7 @@ impl ModCollector<'_, '_> {
1147 self.collect_derives(&attrs, it.ast_id.upcast()); 1156 self.collect_derives(&attrs, it.ast_id.upcast());
1148 1157
1149 def = Some(DefData { 1158 def = Some(DefData {
1150 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } 1159 id: UnionLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1151 .intern(self.def_collector.db) 1160 .intern(self.def_collector.db)
1152 .into(), 1161 .into(),
1153 name: &it.name, 1162 name: &it.name,
@@ -1164,7 +1173,7 @@ impl ModCollector<'_, '_> {
1164 self.collect_derives(&attrs, it.ast_id.upcast()); 1173 self.collect_derives(&attrs, it.ast_id.upcast());
1165 1174
1166 def = Some(DefData { 1175 def = Some(DefData {
1167 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } 1176 id: EnumLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1168 .intern(self.def_collector.db) 1177 .intern(self.def_collector.db)
1169 .into(), 1178 .into(),
1170 name: &it.name, 1179 name: &it.name,
@@ -1178,7 +1187,7 @@ impl ModCollector<'_, '_> {
1178 if let Some(name) = &it.name { 1187 if let Some(name) = &it.name {
1179 def = Some(DefData { 1188 def = Some(DefData {
1180 id: ConstLoc { 1189 id: ConstLoc {
1181 container: container.into(), 1190 container: module.into(),
1182 id: ItemTreeId::new(self.file_id, id), 1191 id: ItemTreeId::new(self.file_id, id),
1183 } 1192 }
1184 .intern(self.def_collector.db) 1193 .intern(self.def_collector.db)
@@ -1193,7 +1202,7 @@ impl ModCollector<'_, '_> {
1193 let it = &self.item_tree[id]; 1202 let it = &self.item_tree[id];
1194 1203
1195 def = Some(DefData { 1204 def = Some(DefData {
1196 id: StaticLoc { container, id: ItemTreeId::new(self.file_id, id) } 1205 id: StaticLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1197 .intern(self.def_collector.db) 1206 .intern(self.def_collector.db)
1198 .into(), 1207 .into(),
1199 name: &it.name, 1208 name: &it.name,
@@ -1205,7 +1214,7 @@ impl ModCollector<'_, '_> {
1205 let it = &self.item_tree[id]; 1214 let it = &self.item_tree[id];
1206 1215
1207 def = Some(DefData { 1216 def = Some(DefData {
1208 id: TraitLoc { container, id: ItemTreeId::new(self.file_id, id) } 1217 id: TraitLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1209 .intern(self.def_collector.db) 1218 .intern(self.def_collector.db)
1210 .into(), 1219 .into(),
1211 name: &it.name, 1220 name: &it.name,
@@ -1218,7 +1227,7 @@ impl ModCollector<'_, '_> {
1218 1227
1219 def = Some(DefData { 1228 def = Some(DefData {
1220 id: TypeAliasLoc { 1229 id: TypeAliasLoc {
1221 container: container.into(), 1230 container: module.into(),
1222 id: ItemTreeId::new(self.file_id, id), 1231 id: ItemTreeId::new(self.file_id, id),
1223 } 1232 }
1224 .intern(self.def_collector.db) 1233 .intern(self.def_collector.db)
@@ -1446,8 +1455,11 @@ impl ModCollector<'_, '_> {
1446 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); 1455 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
1447 1456
1448 // Case 1: try to resolve in legacy scope and expand macro_rules 1457 // Case 1: try to resolve in legacy scope and expand macro_rules
1449 if let Some(macro_call_id) = 1458 if let Ok(Ok(macro_call_id)) = macro_call_as_call_id(
1450 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { 1459 &ast_id,
1460 self.def_collector.db,
1461 self.def_collector.def_map.krate,
1462 |path| {
1451 path.as_ident().and_then(|name| { 1463 path.as_ident().and_then(|name| {
1452 self.def_collector.def_map.with_ancestor_maps( 1464 self.def_collector.def_map.with_ancestor_maps(
1453 self.def_collector.db, 1465 self.def_collector.db,
@@ -1455,8 +1467,9 @@ impl ModCollector<'_, '_> {
1455 &mut |map, module| map[module].scope.get_legacy_macro(&name), 1467 &mut |map, module| map[module].scope.get_legacy_macro(&name),
1456 ) 1468 )
1457 }) 1469 })
1458 }) 1470 },
1459 { 1471 &mut |_err| (),
1472 ) {
1460 self.def_collector.unexpanded_macros.push(MacroDirective { 1473 self.def_collector.unexpanded_macros.push(MacroDirective {
1461 module_id: self.module_id, 1474 module_id: self.module_id,
1462 ast_id, 1475 ast_id,