diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 121 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/mod_resolution.rs | 3 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 46 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/diagnostics.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/globs.rs | 8 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/macros.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/mod_resolution.rs | 4 |
8 files changed, 117 insertions, 89 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 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
20 | use syntax::ast; | 20 | use syntax::ast; |
21 | use test_utils::mark; | ||
22 | use tt::{Leaf, TokenTree}; | 21 | use tt::{Leaf, TokenTree}; |
23 | 22 | ||
24 | use crate::{ | 23 | use 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 | ||
44 | const GLOB_RECURSION_LIMIT: usize = 100; | 45 | const 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, |
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs index af3262439..d5de9899c 100644 --- a/crates/hir_def/src/nameres/mod_resolution.rs +++ b/crates/hir_def/src/nameres/mod_resolution.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | use base_db::{AnchoredPath, FileId}; | 2 | use base_db::{AnchoredPath, FileId}; |
3 | use hir_expand::name::Name; | 3 | use hir_expand::name::Name; |
4 | use syntax::SmolStr; | 4 | use syntax::SmolStr; |
5 | use test_utils::mark; | ||
6 | 5 | ||
7 | use crate::{db::DefDatabase, HirFileId}; | 6 | use crate::{db::DefDatabase, HirFileId}; |
8 | 7 | ||
@@ -28,7 +27,7 @@ impl ModDir { | |||
28 | let depth = self.depth + 1; | 27 | let depth = self.depth + 1; |
29 | if depth > MOD_DEPTH_LIMIT { | 28 | if depth > MOD_DEPTH_LIMIT { |
30 | log::error!("MOD_DEPTH_LIMIT exceeded"); | 29 | log::error!("MOD_DEPTH_LIMIT exceeded"); |
31 | mark::hit!(circular_mods); | 30 | cov_mark::hit!(circular_mods); |
32 | return None; | 31 | return None; |
33 | } | 32 | } |
34 | Some(ModDir { dir_path, root_non_dir_owner, depth }) | 33 | Some(ModDir { dir_path, root_non_dir_owner, depth }) |
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index fdcdc23ae..db459b1ed 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -13,7 +13,6 @@ | |||
13 | use base_db::Edition; | 13 | use base_db::Edition; |
14 | use hir_expand::name; | 14 | use hir_expand::name; |
15 | use hir_expand::name::Name; | 15 | use hir_expand::name::Name; |
16 | use test_utils::mark; | ||
17 | 16 | ||
18 | use crate::{ | 17 | use crate::{ |
19 | db::DefDatabase, | 18 | db::DefDatabase, |
@@ -63,7 +62,7 @@ impl ResolvePathResult { | |||
63 | impl DefMap { | 62 | impl DefMap { |
64 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { | 63 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { |
65 | if name == &name!(self) { | 64 | if name == &name!(self) { |
66 | mark::hit!(extern_crate_self_as); | 65 | cov_mark::hit!(extern_crate_self_as); |
67 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); | 66 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); |
68 | } | 67 | } |
69 | self.extern_prelude | 68 | self.extern_prelude |
@@ -77,7 +76,7 @@ impl DefMap { | |||
77 | original_module: LocalModuleId, | 76 | original_module: LocalModuleId, |
78 | visibility: &RawVisibility, | 77 | visibility: &RawVisibility, |
79 | ) -> Option<Visibility> { | 78 | ) -> Option<Visibility> { |
80 | match visibility { | 79 | let mut vis = match visibility { |
81 | RawVisibility::Module(path) => { | 80 | RawVisibility::Module(path) => { |
82 | let (result, remaining) = | 81 | let (result, remaining) = |
83 | self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); | 82 | self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); |
@@ -86,15 +85,28 @@ impl DefMap { | |||
86 | } | 85 | } |
87 | let types = result.take_types()?; | 86 | let types = result.take_types()?; |
88 | match types { | 87 | match types { |
89 | ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)), | 88 | ModuleDefId::ModuleId(m) => Visibility::Module(m), |
90 | _ => { | 89 | _ => { |
91 | // error: visibility needs to refer to module | 90 | // error: visibility needs to refer to module |
92 | None | 91 | return None; |
93 | } | 92 | } |
94 | } | 93 | } |
95 | } | 94 | } |
96 | RawVisibility::Public => Some(Visibility::Public), | 95 | RawVisibility::Public => Visibility::Public, |
96 | }; | ||
97 | |||
98 | // In block expressions, `self` normally refers to the containing non-block module, and | ||
99 | // `super` to its parent (etc.). However, visibilities must only refer to a module in the | ||
100 | // DefMap they're written in, so we restrict them when that happens. | ||
101 | if let Visibility::Module(m) = vis { | ||
102 | if self.block_id() != m.block { | ||
103 | cov_mark::hit!(adjust_vis_in_block_def_map); | ||
104 | vis = Visibility::Module(self.module_id(self.root())); | ||
105 | log::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis); | ||
106 | } | ||
97 | } | 107 | } |
108 | |||
109 | Some(vis) | ||
98 | } | 110 | } |
99 | 111 | ||
100 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change | 112 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change |
@@ -144,7 +156,7 @@ impl DefMap { | |||
144 | } | 156 | } |
145 | } | 157 | } |
146 | 158 | ||
147 | pub(super) fn resolve_path_fp_with_macro_single( | 159 | fn resolve_path_fp_with_macro_single( |
148 | &self, | 160 | &self, |
149 | db: &dyn DefDatabase, | 161 | db: &dyn DefDatabase, |
150 | mode: ResolveMode, | 162 | mode: ResolveMode, |
@@ -156,12 +168,12 @@ impl DefMap { | |||
156 | let mut curr_per_ns: PerNs = match path.kind { | 168 | let mut curr_per_ns: PerNs = match path.kind { |
157 | PathKind::DollarCrate(krate) => { | 169 | PathKind::DollarCrate(krate) => { |
158 | if krate == self.krate { | 170 | if krate == self.krate { |
159 | mark::hit!(macro_dollar_crate_self); | 171 | cov_mark::hit!(macro_dollar_crate_self); |
160 | PerNs::types(self.crate_root(db).into(), Visibility::Public) | 172 | PerNs::types(self.crate_root(db).into(), Visibility::Public) |
161 | } else { | 173 | } else { |
162 | let def_map = db.crate_def_map(krate); | 174 | let def_map = db.crate_def_map(krate); |
163 | let module = def_map.module_id(def_map.root); | 175 | let module = def_map.module_id(def_map.root); |
164 | mark::hit!(macro_dollar_crate_other); | 176 | cov_mark::hit!(macro_dollar_crate_other); |
165 | PerNs::types(module.into(), Visibility::Public) | 177 | PerNs::types(module.into(), Visibility::Public) |
166 | } | 178 | } |
167 | } | 179 | } |
@@ -297,7 +309,7 @@ impl DefMap { | |||
297 | } | 309 | } |
298 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { | 310 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { |
299 | // enum variant | 311 | // enum variant |
300 | mark::hit!(can_import_enum_variant); | 312 | cov_mark::hit!(can_import_enum_variant); |
301 | let enum_data = db.enum_data(e); | 313 | let enum_data = db.enum_data(e); |
302 | match enum_data.variant(&segment) { | 314 | match enum_data.variant(&segment) { |
303 | Some(local_id) => { | 315 | Some(local_id) => { |
@@ -372,10 +384,16 @@ impl DefMap { | |||
372 | } | 384 | } |
373 | } | 385 | } |
374 | }; | 386 | }; |
375 | let from_extern_prelude = self | 387 | // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude |
376 | .extern_prelude | 388 | // from the crate DefMap. |
377 | .get(name) | 389 | let from_extern_prelude = match self.block { |
378 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)); | 390 | Some(_) => PerNs::none(), |
391 | None => self | ||
392 | .extern_prelude | ||
393 | .get(name) | ||
394 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)), | ||
395 | }; | ||
396 | |||
379 | let from_prelude = self.resolve_in_prelude(db, name); | 397 | let from_prelude = self.resolve_in_prelude(db, name); |
380 | 398 | ||
381 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) | 399 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) |
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index bd3e2701b..de3aa4f9a 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs | |||
@@ -9,7 +9,6 @@ use std::sync::Arc; | |||
9 | 9 | ||
10 | use base_db::{fixture::WithFixture, SourceDatabase}; | 10 | use base_db::{fixture::WithFixture, SourceDatabase}; |
11 | use expect_test::{expect, Expect}; | 11 | use expect_test::{expect, Expect}; |
12 | use test_utils::mark; | ||
13 | 12 | ||
14 | use crate::{db::DefDatabase, test_db::TestDB}; | 13 | use crate::{db::DefDatabase, test_db::TestDB}; |
15 | 14 | ||
@@ -136,7 +135,7 @@ mod m { | |||
136 | 135 | ||
137 | #[test] | 136 | #[test] |
138 | fn bogus_paths() { | 137 | fn bogus_paths() { |
139 | mark::check!(bogus_paths); | 138 | cov_mark::check!(bogus_paths); |
140 | check( | 139 | check( |
141 | r#" | 140 | r#" |
142 | //- /lib.rs | 141 | //- /lib.rs |
@@ -243,7 +242,7 @@ pub struct Baz; | |||
243 | 242 | ||
244 | #[test] | 243 | #[test] |
245 | fn std_prelude() { | 244 | fn std_prelude() { |
246 | mark::check!(std_prelude); | 245 | cov_mark::check!(std_prelude); |
247 | check( | 246 | check( |
248 | r#" | 247 | r#" |
249 | //- /main.rs crate:main deps:test_crate | 248 | //- /main.rs crate:main deps:test_crate |
@@ -267,7 +266,7 @@ pub enum Foo { Bar, Baz }; | |||
267 | 266 | ||
268 | #[test] | 267 | #[test] |
269 | fn can_import_enum_variant() { | 268 | fn can_import_enum_variant() { |
270 | mark::check!(can_import_enum_variant); | 269 | cov_mark::check!(can_import_enum_variant); |
271 | check( | 270 | check( |
272 | r#" | 271 | r#" |
273 | enum E { V } | 272 | enum E { V } |
@@ -628,7 +627,7 @@ use crate::reex::*; | |||
628 | 627 | ||
629 | #[test] | 628 | #[test] |
630 | fn underscore_pub_crate_reexport() { | 629 | fn underscore_pub_crate_reexport() { |
631 | mark::check!(upgrade_underscore_visibility); | 630 | cov_mark::check!(upgrade_underscore_visibility); |
632 | check( | 631 | check( |
633 | r#" | 632 | r#" |
634 | //- /main.rs crate:main deps:lib | 633 | //- /main.rs crate:main deps:lib |
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index e8e72e5ef..d5ef8ceb5 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | use base_db::fixture::WithFixture; | 1 | use base_db::fixture::WithFixture; |
2 | use test_utils::mark; | ||
3 | 2 | ||
4 | use crate::test_db::TestDB; | 3 | use crate::test_db::TestDB; |
5 | 4 | ||
@@ -63,7 +62,7 @@ fn unresolved_extern_crate() { | |||
63 | 62 | ||
64 | #[test] | 63 | #[test] |
65 | fn extern_crate_self_as() { | 64 | fn extern_crate_self_as() { |
66 | mark::check!(extern_crate_self_as); | 65 | cov_mark::check!(extern_crate_self_as); |
67 | check_diagnostics( | 66 | check_diagnostics( |
68 | r" | 67 | r" |
69 | //- /lib.rs | 68 | //- /lib.rs |
@@ -140,7 +139,7 @@ fn inactive_item() { | |||
140 | /// Tests that `cfg` attributes behind `cfg_attr` is handled properly. | 139 | /// Tests that `cfg` attributes behind `cfg_attr` is handled properly. |
141 | #[test] | 140 | #[test] |
142 | fn inactive_via_cfg_attr() { | 141 | fn inactive_via_cfg_attr() { |
143 | mark::check!(cfg_attr_active); | 142 | cov_mark::check!(cfg_attr_active); |
144 | check_diagnostics( | 143 | check_diagnostics( |
145 | r#" | 144 | r#" |
146 | //- /lib.rs | 145 | //- /lib.rs |
diff --git a/crates/hir_def/src/nameres/tests/globs.rs b/crates/hir_def/src/nameres/tests/globs.rs index 2ae836e3c..17426d54d 100644 --- a/crates/hir_def/src/nameres/tests/globs.rs +++ b/crates/hir_def/src/nameres/tests/globs.rs | |||
@@ -148,7 +148,7 @@ pub(crate) struct PubCrateStruct; | |||
148 | 148 | ||
149 | #[test] | 149 | #[test] |
150 | fn glob_across_crates() { | 150 | fn glob_across_crates() { |
151 | mark::check!(glob_across_crates); | 151 | cov_mark::check!(glob_across_crates); |
152 | check( | 152 | check( |
153 | r#" | 153 | r#" |
154 | //- /main.rs crate:main deps:test_crate | 154 | //- /main.rs crate:main deps:test_crate |
@@ -184,7 +184,7 @@ struct Foo; | |||
184 | 184 | ||
185 | #[test] | 185 | #[test] |
186 | fn glob_enum() { | 186 | fn glob_enum() { |
187 | mark::check!(glob_enum); | 187 | cov_mark::check!(glob_enum); |
188 | check( | 188 | check( |
189 | r#" | 189 | r#" |
190 | enum Foo { Bar, Baz } | 190 | enum Foo { Bar, Baz } |
@@ -201,7 +201,7 @@ use self::Foo::*; | |||
201 | 201 | ||
202 | #[test] | 202 | #[test] |
203 | fn glob_enum_group() { | 203 | fn glob_enum_group() { |
204 | mark::check!(glob_enum_group); | 204 | cov_mark::check!(glob_enum_group); |
205 | check( | 205 | check( |
206 | r#" | 206 | r#" |
207 | enum Foo { Bar, Baz } | 207 | enum Foo { Bar, Baz } |
@@ -218,7 +218,7 @@ use self::Foo::{*}; | |||
218 | 218 | ||
219 | #[test] | 219 | #[test] |
220 | fn glob_shadowed_def() { | 220 | fn glob_shadowed_def() { |
221 | mark::check!(import_shadowed); | 221 | cov_mark::check!(import_shadowed); |
222 | check( | 222 | check( |
223 | r#" | 223 | r#" |
224 | //- /lib.rs | 224 | //- /lib.rs |
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs index 36ed5e8ce..f65a655bf 100644 --- a/crates/hir_def/src/nameres/tests/macros.rs +++ b/crates/hir_def/src/nameres/tests/macros.rs | |||
@@ -210,7 +210,7 @@ macro_rules! bar { | |||
210 | 210 | ||
211 | #[test] | 211 | #[test] |
212 | fn macro_rules_from_other_crates_are_visible_with_macro_use() { | 212 | fn macro_rules_from_other_crates_are_visible_with_macro_use() { |
213 | mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use); | 213 | cov_mark::check!(macro_rules_from_other_crates_are_visible_with_macro_use); |
214 | check( | 214 | check( |
215 | r#" | 215 | r#" |
216 | //- /main.rs crate:main deps:foo | 216 | //- /main.rs crate:main deps:foo |
@@ -260,7 +260,7 @@ mod priv_mod { | |||
260 | 260 | ||
261 | #[test] | 261 | #[test] |
262 | fn prelude_is_macro_use() { | 262 | fn prelude_is_macro_use() { |
263 | mark::check!(prelude_is_macro_use); | 263 | cov_mark::check!(prelude_is_macro_use); |
264 | check( | 264 | check( |
265 | r#" | 265 | r#" |
266 | //- /main.rs crate:main deps:foo | 266 | //- /main.rs crate:main deps:foo |
@@ -550,7 +550,7 @@ mod m { | |||
550 | 550 | ||
551 | #[test] | 551 | #[test] |
552 | fn macro_dollar_crate_is_correct_in_item() { | 552 | fn macro_dollar_crate_is_correct_in_item() { |
553 | mark::check!(macro_dollar_crate_self); | 553 | cov_mark::check!(macro_dollar_crate_self); |
554 | check( | 554 | check( |
555 | r#" | 555 | r#" |
556 | //- /main.rs crate:main deps:foo | 556 | //- /main.rs crate:main deps:foo |
@@ -608,7 +608,7 @@ struct Baz; | |||
608 | 608 | ||
609 | #[test] | 609 | #[test] |
610 | fn macro_dollar_crate_is_correct_in_indirect_deps() { | 610 | fn macro_dollar_crate_is_correct_in_indirect_deps() { |
611 | mark::check!(macro_dollar_crate_other); | 611 | cov_mark::check!(macro_dollar_crate_other); |
612 | // From std | 612 | // From std |
613 | check( | 613 | check( |
614 | r#" | 614 | r#" |
@@ -686,7 +686,7 @@ pub trait Clone {} | |||
686 | 686 | ||
687 | #[test] | 687 | #[test] |
688 | fn macro_expansion_overflow() { | 688 | fn macro_expansion_overflow() { |
689 | mark::check!(macro_expansion_overflow); | 689 | cov_mark::check!(macro_expansion_overflow); |
690 | check( | 690 | check( |
691 | r#" | 691 | r#" |
692 | macro_rules! a { | 692 | macro_rules! a { |
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs index e80b593aa..dfbbad1f9 100644 --- a/crates/hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs | |||
@@ -2,7 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | #[test] | 3 | #[test] |
4 | fn name_res_works_for_broken_modules() { | 4 | fn name_res_works_for_broken_modules() { |
5 | mark::check!(name_res_works_for_broken_modules); | 5 | cov_mark::check!(name_res_works_for_broken_modules); |
6 | check( | 6 | check( |
7 | r" | 7 | r" |
8 | //- /lib.rs | 8 | //- /lib.rs |
@@ -774,7 +774,7 @@ struct X; | |||
774 | 774 | ||
775 | #[test] | 775 | #[test] |
776 | fn circular_mods() { | 776 | fn circular_mods() { |
777 | mark::check!(circular_mods); | 777 | cov_mark::check!(circular_mods); |
778 | compute_crate_def_map( | 778 | compute_crate_def_map( |
779 | r#" | 779 | r#" |
780 | //- /lib.rs | 780 | //- /lib.rs |