diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 212 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 163 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/diagnostics.rs | 16 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/macros.rs | 14 |
5 files changed, 294 insertions, 126 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 0cd61698c..e51d89b43 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -13,7 +13,7 @@ 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}; |
@@ -24,38 +24,43 @@ use tt::{Leaf, TokenTree}; | |||
24 | use crate::{ | 24 | use crate::{ |
25 | attr::Attrs, | 25 | attr::Attrs, |
26 | db::DefDatabase, | 26 | db::DefDatabase, |
27 | item_attr_as_call_id, | ||
27 | item_scope::{ImportType, PerNsGlobImports}, | 28 | item_scope::{ImportType, PerNsGlobImports}, |
28 | item_tree::{ | 29 | item_tree::{ |
29 | self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, | 30 | self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, |
30 | StructDefKind, | 31 | StructDefKind, |
31 | }, | 32 | }, |
33 | macro_call_as_call_id, | ||
32 | nameres::{ | 34 | nameres::{ |
33 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, | 35 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, |
34 | BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, | 36 | BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode, |
35 | }, | 37 | }, |
36 | path::{ImportAlias, ModPath, PathKind}, | 38 | path::{ImportAlias, ModPath, PathKind}, |
37 | per_ns::PerNs, | 39 | per_ns::PerNs, |
38 | visibility::{RawVisibility, Visibility}, | 40 | visibility::{RawVisibility, Visibility}, |
39 | AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, | 41 | AdtId, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, |
40 | FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, | 42 | ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, |
41 | TraitLoc, TypeAliasLoc, UnionLoc, | 43 | UnionLoc, UnresolvedMacro, |
42 | }; | 44 | }; |
43 | 45 | ||
44 | const GLOB_RECURSION_LIMIT: usize = 100; | 46 | const GLOB_RECURSION_LIMIT: usize = 100; |
45 | const EXPANSION_DEPTH_LIMIT: usize = 128; | 47 | const EXPANSION_DEPTH_LIMIT: usize = 128; |
46 | const FIXED_POINT_LIMIT: usize = 8192; | 48 | const FIXED_POINT_LIMIT: usize = 8192; |
47 | 49 | ||
48 | pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 50 | pub(super) fn collect_defs( |
51 | db: &dyn DefDatabase, | ||
52 | mut def_map: DefMap, | ||
53 | block: Option<AstId<ast::BlockExpr>>, | ||
54 | ) -> DefMap { | ||
49 | let crate_graph = db.crate_graph(); | 55 | let crate_graph = db.crate_graph(); |
50 | 56 | ||
51 | // populate external prelude | 57 | // populate external prelude |
52 | for dep in &crate_graph[def_map.krate].dependencies { | 58 | for dep in &crate_graph[def_map.krate].dependencies { |
53 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); | 59 | log::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id); |
54 | let dep_def_map = db.crate_def_map(dep.crate_id); | 60 | let dep_def_map = db.crate_def_map(dep.crate_id); |
55 | def_map.extern_prelude.insert( | 61 | def_map |
56 | dep.as_name(), | 62 | .extern_prelude |
57 | ModuleId { krate: dep.crate_id, local_id: dep_def_map.root }.into(), | 63 | .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into()); |
58 | ); | ||
59 | 64 | ||
60 | // look for the prelude | 65 | // look for the prelude |
61 | // If the dependency defines a prelude, we overwrite an already defined | 66 | // If the dependency defines a prelude, we overwrite an already defined |
@@ -93,6 +98,14 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr | |||
93 | exports_proc_macros: false, | 98 | exports_proc_macros: false, |
94 | from_glob_import: Default::default(), | 99 | from_glob_import: Default::default(), |
95 | }; | 100 | }; |
101 | match block { | ||
102 | Some(block) => { | ||
103 | collector.seed_with_inner(block); | ||
104 | } | ||
105 | None => { | ||
106 | collector.seed_with_top_level(); | ||
107 | } | ||
108 | } | ||
96 | collector.collect(); | 109 | collector.collect(); |
97 | collector.finish() | 110 | collector.finish() |
98 | } | 111 | } |
@@ -210,7 +223,7 @@ struct DefData<'a> { | |||
210 | /// Walks the tree of module recursively | 223 | /// Walks the tree of module recursively |
211 | struct DefCollector<'a> { | 224 | struct DefCollector<'a> { |
212 | db: &'a dyn DefDatabase, | 225 | db: &'a dyn DefDatabase, |
213 | def_map: CrateDefMap, | 226 | def_map: DefMap, |
214 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, | 227 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>, |
215 | unresolved_imports: Vec<ImportDirective>, | 228 | unresolved_imports: Vec<ImportDirective>, |
216 | resolved_imports: Vec<ImportDirective>, | 229 | resolved_imports: Vec<ImportDirective>, |
@@ -228,7 +241,7 @@ struct DefCollector<'a> { | |||
228 | } | 241 | } |
229 | 242 | ||
230 | impl DefCollector<'_> { | 243 | impl DefCollector<'_> { |
231 | fn collect(&mut self) { | 244 | fn seed_with_top_level(&mut self) { |
232 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; | 245 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; |
233 | let item_tree = self.db.item_tree(file_id.into()); | 246 | let item_tree = self.db.item_tree(file_id.into()); |
234 | let module_id = self.def_map.root; | 247 | let module_id = self.def_map.root; |
@@ -248,7 +261,30 @@ impl DefCollector<'_> { | |||
248 | } | 261 | } |
249 | .collect(item_tree.top_level_items()); | 262 | .collect(item_tree.top_level_items()); |
250 | } | 263 | } |
264 | } | ||
251 | 265 | ||
266 | fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) { | ||
267 | let item_tree = self.db.item_tree(block.file_id); | ||
268 | let module_id = self.def_map.root; | ||
269 | self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block }; | ||
270 | if item_tree | ||
271 | .top_level_attrs(self.db, self.def_map.krate) | ||
272 | .cfg() | ||
273 | .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) | ||
274 | { | ||
275 | ModCollector { | ||
276 | def_collector: &mut *self, | ||
277 | macro_depth: 0, | ||
278 | module_id, | ||
279 | file_id: block.file_id, | ||
280 | item_tree: &item_tree, | ||
281 | mod_dir: ModDir::root(), | ||
282 | } | ||
283 | .collect(item_tree.inner_items_of_block(block.value)); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | fn collect(&mut self) { | ||
252 | // main name resolution fixed-point loop. | 288 | // main name resolution fixed-point loop. |
253 | let mut i = 0; | 289 | let mut i = 0; |
254 | loop { | 290 | loop { |
@@ -296,11 +332,9 @@ impl DefCollector<'_> { | |||
296 | // exported in type/value namespace. This function reduces the visibility of all items | 332 | // exported in type/value namespace. This function reduces the visibility of all items |
297 | // in the crate root that aren't proc macros. | 333 | // in the crate root that aren't proc macros. |
298 | let root = self.def_map.root; | 334 | let root = self.def_map.root; |
335 | let module_id = self.def_map.module_id(root); | ||
299 | let root = &mut self.def_map.modules[root]; | 336 | let root = &mut self.def_map.modules[root]; |
300 | root.scope.censor_non_proc_macros(ModuleId { | 337 | root.scope.censor_non_proc_macros(module_id); |
301 | krate: self.def_map.krate, | ||
302 | local_id: self.def_map.root, | ||
303 | }); | ||
304 | } | 338 | } |
305 | } | 339 | } |
306 | 340 | ||
@@ -542,7 +576,7 @@ impl DefCollector<'_> { | |||
542 | } else if m.krate != self.def_map.krate { | 576 | } else if m.krate != self.def_map.krate { |
543 | mark::hit!(glob_across_crates); | 577 | mark::hit!(glob_across_crates); |
544 | // glob import from other crate => we can just import everything once | 578 | // glob import from other crate => we can just import everything once |
545 | let item_map = self.db.crate_def_map(m.krate); | 579 | let item_map = m.def_map(self.db); |
546 | let scope = &item_map[m.local_id].scope; | 580 | let scope = &item_map[m.local_id].scope; |
547 | 581 | ||
548 | // Module scoped macros is included | 582 | // Module scoped macros is included |
@@ -560,7 +594,13 @@ impl DefCollector<'_> { | |||
560 | // glob import from same crate => we do an initial | 594 | // glob import from same crate => we do an initial |
561 | // import, and then need to propagate any further | 595 | // import, and then need to propagate any further |
562 | // additions | 596 | // additions |
563 | let scope = &self.def_map[m.local_id].scope; | 597 | let def_map; |
598 | let scope = if m.block == self.def_map.block_id() { | ||
599 | &self.def_map[m.local_id].scope | ||
600 | } else { | ||
601 | def_map = m.def_map(self.db); | ||
602 | &def_map[m.local_id].scope | ||
603 | }; | ||
564 | 604 | ||
565 | // Module scoped macros is included | 605 | // Module scoped macros is included |
566 | let items = scope | 606 | let items = scope |
@@ -570,7 +610,7 @@ impl DefCollector<'_> { | |||
570 | ( | 610 | ( |
571 | n, | 611 | n, |
572 | res.filter_visibility(|v| { | 612 | res.filter_visibility(|v| { |
573 | v.is_visible_from_def_map(&self.def_map, module_id) | 613 | v.is_visible_from_def_map(self.db, &self.def_map, module_id) |
574 | }), | 614 | }), |
575 | ) | 615 | ) |
576 | }) | 616 | }) |
@@ -617,7 +657,7 @@ impl DefCollector<'_> { | |||
617 | } | 657 | } |
618 | } | 658 | } |
619 | } else { | 659 | } else { |
620 | match import.path.segments.last() { | 660 | match import.path.segments().last() { |
621 | Some(last_segment) => { | 661 | Some(last_segment) => { |
622 | let name = match &import.alias { | 662 | let name = match &import.alias { |
623 | Some(ImportAlias::Alias(name)) => Some(name.clone()), | 663 | Some(ImportAlias::Alias(name)) => Some(name.clone()), |
@@ -723,7 +763,7 @@ impl DefCollector<'_> { | |||
723 | .filter(|(glob_importing_module, _)| { | 763 | .filter(|(glob_importing_module, _)| { |
724 | // we know all resolutions have the same visibility (`vis`), so we | 764 | // we know all resolutions have the same visibility (`vis`), so we |
725 | // just need to check that once | 765 | // just need to check that once |
726 | vis.is_visible_from_def_map(&self.def_map, *glob_importing_module) | 766 | vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module) |
727 | }) | 767 | }) |
728 | .cloned() | 768 | .cloned() |
729 | .collect::<Vec<_>>(); | 769 | .collect::<Vec<_>>(); |
@@ -752,8 +792,11 @@ impl DefCollector<'_> { | |||
752 | return false; | 792 | return false; |
753 | } | 793 | } |
754 | 794 | ||
755 | if let Some(call_id) = | 795 | match macro_call_as_call_id( |
756 | directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { | 796 | &directive.ast_id, |
797 | self.db, | ||
798 | self.def_map.krate, | ||
799 | |path| { | ||
757 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | 800 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
758 | self.db, | 801 | self.db, |
759 | ResolveMode::Other, | 802 | ResolveMode::Other, |
@@ -762,24 +805,29 @@ impl DefCollector<'_> { | |||
762 | BuiltinShadowMode::Module, | 805 | BuiltinShadowMode::Module, |
763 | ); | 806 | ); |
764 | resolved_res.resolved_def.take_macros() | 807 | resolved_res.resolved_def.take_macros() |
765 | }) | 808 | }, |
766 | { | 809 | &mut |_err| (), |
767 | resolved.push((directive.module_id, call_id, directive.depth)); | 810 | ) { |
768 | res = ReachedFixedPoint::No; | 811 | Ok(Ok(call_id)) => { |
769 | return false; | 812 | resolved.push((directive.module_id, call_id, directive.depth)); |
813 | res = ReachedFixedPoint::No; | ||
814 | return false; | ||
815 | } | ||
816 | Err(UnresolvedMacro) | Ok(Err(_)) => {} | ||
770 | } | 817 | } |
771 | 818 | ||
772 | true | 819 | true |
773 | }); | 820 | }); |
774 | attribute_macros.retain(|directive| { | 821 | attribute_macros.retain(|directive| { |
775 | if let Some(call_id) = | 822 | match item_attr_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| { |
776 | directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { | 823 | self.resolve_attribute_macro(&directive, &path) |
777 | self.resolve_attribute_macro(&directive, &path) | 824 | }) { |
778 | }) | 825 | Ok(call_id) => { |
779 | { | 826 | resolved.push((directive.module_id, call_id, 0)); |
780 | resolved.push((directive.module_id, call_id, 0)); | 827 | res = ReachedFixedPoint::No; |
781 | res = ReachedFixedPoint::No; | 828 | return false; |
782 | return false; | 829 | } |
830 | Err(UnresolvedMacro) => (), | ||
783 | } | 831 | } |
784 | 832 | ||
785 | true | 833 | true |
@@ -859,12 +907,13 @@ impl DefCollector<'_> { | |||
859 | .collect(item_tree.top_level_items()); | 907 | .collect(item_tree.top_level_items()); |
860 | } | 908 | } |
861 | 909 | ||
862 | fn finish(mut self) -> CrateDefMap { | 910 | fn finish(mut self) -> DefMap { |
863 | // Emit diagnostics for all remaining unexpanded macros. | 911 | // Emit diagnostics for all remaining unexpanded macros. |
864 | 912 | ||
865 | for directive in &self.unexpanded_macros { | 913 | for directive in &self.unexpanded_macros { |
866 | let mut error = None; | 914 | let mut error = None; |
867 | directive.ast_id.as_call_id_with_errors( | 915 | match macro_call_as_call_id( |
916 | &directive.ast_id, | ||
868 | self.db, | 917 | self.db, |
869 | self.def_map.krate, | 918 | self.def_map.krate, |
870 | |path| { | 919 | |path| { |
@@ -880,15 +929,15 @@ impl DefCollector<'_> { | |||
880 | &mut |e| { | 929 | &mut |e| { |
881 | error.get_or_insert(e); | 930 | error.get_or_insert(e); |
882 | }, | 931 | }, |
883 | ); | 932 | ) { |
884 | 933 | Ok(_) => (), | |
885 | if let Some(err) = error { | 934 | Err(UnresolvedMacro) => { |
886 | self.def_map.diagnostics.push(DefDiagnostic::macro_error( | 935 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( |
887 | directive.module_id, | 936 | directive.module_id, |
888 | MacroCallKind::FnLike(directive.ast_id.ast_id), | 937 | directive.ast_id.ast_id, |
889 | err.to_string(), | 938 | )); |
890 | )); | 939 | } |
891 | } | 940 | }; |
892 | } | 941 | } |
893 | 942 | ||
894 | // Emit diagnostics for all remaining unresolved imports. | 943 | // Emit diagnostics for all remaining unresolved imports. |
@@ -918,7 +967,7 @@ impl DefCollector<'_> { | |||
918 | let item_tree = self.db.item_tree(import.file_id); | 967 | let item_tree = self.db.item_tree(import.file_id); |
919 | let import_data = &item_tree[import.value]; | 968 | let import_data = &item_tree[import.value]; |
920 | 969 | ||
921 | match (import_data.path.segments.first(), &import_data.path.kind) { | 970 | match (import_data.path.segments().first(), &import_data.path.kind) { |
922 | (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { | 971 | (Some(krate), PathKind::Plain) | (Some(krate), PathKind::Abs) => { |
923 | if diagnosed_extern_crates.contains(krate) { | 972 | if diagnosed_extern_crates.contains(krate) { |
924 | continue; | 973 | continue; |
@@ -993,8 +1042,7 @@ impl ModCollector<'_, '_> { | |||
993 | continue; | 1042 | continue; |
994 | } | 1043 | } |
995 | } | 1044 | } |
996 | let module = | 1045 | let module = self.def_collector.def_map.module_id(self.module_id); |
997 | ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; | ||
998 | let container = ContainerId::ModuleId(module); | 1046 | let container = ContainerId::ModuleId(module); |
999 | 1047 | ||
1000 | let mut def = None; | 1048 | let mut def = None; |
@@ -1061,10 +1109,7 @@ impl ModCollector<'_, '_> { | |||
1061 | } | 1109 | } |
1062 | } | 1110 | } |
1063 | ModItem::Impl(imp) => { | 1111 | ModItem::Impl(imp) => { |
1064 | let module = ModuleId { | 1112 | let module = self.def_collector.def_map.module_id(self.module_id); |
1065 | krate: self.def_collector.def_map.krate, | ||
1066 | local_id: self.module_id, | ||
1067 | }; | ||
1068 | let container = ContainerId::ModuleId(module); | 1113 | let container = ContainerId::ModuleId(module); |
1069 | let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } | 1114 | let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } |
1070 | .intern(self.def_collector.db); | 1115 | .intern(self.def_collector.db); |
@@ -1245,12 +1290,8 @@ impl ModCollector<'_, '_> { | |||
1245 | // out of line module, resolve, parse and recurse | 1290 | // out of line module, resolve, parse and recurse |
1246 | ModKind::Outline {} => { | 1291 | ModKind::Outline {} => { |
1247 | let ast_id = AstId::new(self.file_id, module.ast_id); | 1292 | let ast_id = AstId::new(self.file_id, module.ast_id); |
1248 | match self.mod_dir.resolve_declaration( | 1293 | let db = self.def_collector.db; |
1249 | self.def_collector.db, | 1294 | match self.mod_dir.resolve_declaration(db, self.file_id, &module.name, path_attr) { |
1250 | self.file_id, | ||
1251 | &module.name, | ||
1252 | path_attr, | ||
1253 | ) { | ||
1254 | Ok((file_id, is_mod_rs, mod_dir)) => { | 1295 | Ok((file_id, is_mod_rs, mod_dir)) => { |
1255 | let module_id = self.push_child_module( | 1296 | let module_id = self.push_child_module( |
1256 | module.name.clone(), | 1297 | module.name.clone(), |
@@ -1258,7 +1299,7 @@ impl ModCollector<'_, '_> { | |||
1258 | Some((file_id, is_mod_rs)), | 1299 | Some((file_id, is_mod_rs)), |
1259 | &self.item_tree[module.visibility], | 1300 | &self.item_tree[module.visibility], |
1260 | ); | 1301 | ); |
1261 | let item_tree = self.def_collector.db.item_tree(file_id.into()); | 1302 | let item_tree = db.item_tree(file_id.into()); |
1262 | ModCollector { | 1303 | ModCollector { |
1263 | def_collector: &mut *self.def_collector, | 1304 | def_collector: &mut *self.def_collector, |
1264 | macro_depth: self.macro_depth, | 1305 | macro_depth: self.macro_depth, |
@@ -1268,7 +1309,12 @@ impl ModCollector<'_, '_> { | |||
1268 | mod_dir, | 1309 | mod_dir, |
1269 | } | 1310 | } |
1270 | .collect(item_tree.top_level_items()); | 1311 | .collect(item_tree.top_level_items()); |
1271 | if is_macro_use { | 1312 | if is_macro_use |
1313 | || item_tree | ||
1314 | .top_level_attrs(db, self.def_collector.def_map.krate) | ||
1315 | .by_key("macro_use") | ||
1316 | .exists() | ||
1317 | { | ||
1272 | self.import_all_legacy_macros(module_id); | 1318 | self.import_all_legacy_macros(module_id); |
1273 | } | 1319 | } |
1274 | } | 1320 | } |
@@ -1307,7 +1353,7 @@ impl ModCollector<'_, '_> { | |||
1307 | modules[res].scope.define_legacy_macro(name, mac) | 1353 | modules[res].scope.define_legacy_macro(name, mac) |
1308 | } | 1354 | } |
1309 | modules[self.module_id].children.insert(name.clone(), res); | 1355 | modules[self.module_id].children.insert(name.clone(), res); |
1310 | let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; | 1356 | let module = self.def_collector.def_map.module_id(res); |
1311 | let def: ModuleDefId = module.into(); | 1357 | let def: ModuleDefId = module.into(); |
1312 | self.def_collector.def_map.modules[self.module_id].scope.define_def(def); | 1358 | self.def_collector.def_map.modules[self.module_id].scope.define_def(def); |
1313 | self.def_collector.update( | 1359 | self.def_collector.update( |
@@ -1411,13 +1457,21 @@ impl ModCollector<'_, '_> { | |||
1411 | let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); | 1457 | let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); |
1412 | 1458 | ||
1413 | // Case 1: try to resolve in legacy scope and expand macro_rules | 1459 | // Case 1: try to resolve in legacy scope and expand macro_rules |
1414 | if let Some(macro_call_id) = | 1460 | if let Ok(Ok(macro_call_id)) = macro_call_as_call_id( |
1415 | ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { | 1461 | &ast_id, |
1462 | self.def_collector.db, | ||
1463 | self.def_collector.def_map.krate, | ||
1464 | |path| { | ||
1416 | path.as_ident().and_then(|name| { | 1465 | path.as_ident().and_then(|name| { |
1417 | self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) | 1466 | self.def_collector.def_map.with_ancestor_maps( |
1467 | self.def_collector.db, | ||
1468 | self.module_id, | ||
1469 | &mut |map, module| map[module].scope.get_legacy_macro(&name), | ||
1470 | ) | ||
1418 | }) | 1471 | }) |
1419 | }) | 1472 | }, |
1420 | { | 1473 | &mut |_err| (), |
1474 | ) { | ||
1421 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1475 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1422 | module_id: self.module_id, | 1476 | module_id: self.module_id, |
1423 | ast_id, | 1477 | ast_id, |
@@ -1470,11 +1524,10 @@ impl ModCollector<'_, '_> { | |||
1470 | mod tests { | 1524 | mod tests { |
1471 | use crate::{db::DefDatabase, test_db::TestDB}; | 1525 | use crate::{db::DefDatabase, test_db::TestDB}; |
1472 | use base_db::{fixture::WithFixture, SourceDatabase}; | 1526 | use base_db::{fixture::WithFixture, SourceDatabase}; |
1473 | use la_arena::Arena; | ||
1474 | 1527 | ||
1475 | use super::*; | 1528 | use super::*; |
1476 | 1529 | ||
1477 | fn do_collect_defs(db: &dyn DefDatabase, def_map: CrateDefMap) -> CrateDefMap { | 1530 | fn do_collect_defs(db: &dyn DefDatabase, def_map: DefMap) -> DefMap { |
1478 | let mut collector = DefCollector { | 1531 | let mut collector = DefCollector { |
1479 | db, | 1532 | db, |
1480 | def_map, | 1533 | def_map, |
@@ -1489,28 +1542,17 @@ mod tests { | |||
1489 | exports_proc_macros: false, | 1542 | exports_proc_macros: false, |
1490 | from_glob_import: Default::default(), | 1543 | from_glob_import: Default::default(), |
1491 | }; | 1544 | }; |
1545 | collector.seed_with_top_level(); | ||
1492 | collector.collect(); | 1546 | collector.collect(); |
1493 | collector.def_map | 1547 | collector.def_map |
1494 | } | 1548 | } |
1495 | 1549 | ||
1496 | fn do_resolve(code: &str) -> CrateDefMap { | 1550 | fn do_resolve(code: &str) -> DefMap { |
1497 | let (db, _file_id) = TestDB::with_single_file(&code); | 1551 | let (db, _file_id) = TestDB::with_single_file(&code); |
1498 | let krate = db.test_crate(); | 1552 | let krate = db.test_crate(); |
1499 | 1553 | ||
1500 | let def_map = { | 1554 | let edition = db.crate_graph()[krate].edition; |
1501 | let edition = db.crate_graph()[krate].edition; | 1555 | let def_map = DefMap::empty(krate, edition); |
1502 | let mut modules: Arena<ModuleData> = Arena::default(); | ||
1503 | let root = modules.alloc(ModuleData::default()); | ||
1504 | CrateDefMap { | ||
1505 | krate, | ||
1506 | edition, | ||
1507 | extern_prelude: FxHashMap::default(), | ||
1508 | prelude: None, | ||
1509 | root, | ||
1510 | modules, | ||
1511 | diagnostics: Vec::new(), | ||
1512 | } | ||
1513 | }; | ||
1514 | do_collect_defs(&db, def_map) | 1556 | do_collect_defs(&db, def_map) |
1515 | } | 1557 | } |
1516 | 1558 | ||
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 88e10574e..dd1db0094 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -10,20 +10,19 @@ | |||
10 | //! | 10 | //! |
11 | //! `ReachedFixedPoint` signals about this. | 11 | //! `ReachedFixedPoint` signals about this. |
12 | 12 | ||
13 | use std::iter::successors; | ||
14 | |||
15 | use base_db::Edition; | 13 | use base_db::Edition; |
14 | use hir_expand::name; | ||
16 | use hir_expand::name::Name; | 15 | use hir_expand::name::Name; |
17 | use test_utils::mark; | 16 | use test_utils::mark; |
18 | 17 | ||
19 | use crate::{ | 18 | use crate::{ |
20 | db::DefDatabase, | 19 | db::DefDatabase, |
21 | item_scope::BUILTIN_SCOPE, | 20 | item_scope::BUILTIN_SCOPE, |
22 | nameres::{BuiltinShadowMode, CrateDefMap}, | 21 | nameres::{BuiltinShadowMode, DefMap}, |
23 | path::{ModPath, PathKind}, | 22 | path::{ModPath, PathKind}, |
24 | per_ns::PerNs, | 23 | per_ns::PerNs, |
25 | visibility::{RawVisibility, Visibility}, | 24 | visibility::{RawVisibility, Visibility}, |
26 | AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, | 25 | AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, |
27 | }; | 26 | }; |
28 | 27 | ||
29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 28 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -61,8 +60,12 @@ impl ResolvePathResult { | |||
61 | } | 60 | } |
62 | } | 61 | } |
63 | 62 | ||
64 | impl CrateDefMap { | 63 | impl DefMap { |
65 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { | 64 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { |
65 | if name == &name!(self) { | ||
66 | mark::hit!(extern_crate_self_as); | ||
67 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); | ||
68 | } | ||
66 | self.extern_prelude | 69 | self.extern_prelude |
67 | .get(name) | 70 | .get(name) |
68 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) | 71 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) |
@@ -74,7 +77,7 @@ impl CrateDefMap { | |||
74 | original_module: LocalModuleId, | 77 | original_module: LocalModuleId, |
75 | visibility: &RawVisibility, | 78 | visibility: &RawVisibility, |
76 | ) -> Option<Visibility> { | 79 | ) -> Option<Visibility> { |
77 | match visibility { | 80 | let mut vis = match visibility { |
78 | RawVisibility::Module(path) => { | 81 | RawVisibility::Module(path) => { |
79 | let (result, remaining) = | 82 | let (result, remaining) = |
80 | self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); | 83 | self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); |
@@ -83,15 +86,28 @@ impl CrateDefMap { | |||
83 | } | 86 | } |
84 | let types = result.take_types()?; | 87 | let types = result.take_types()?; |
85 | match types { | 88 | match types { |
86 | ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)), | 89 | ModuleDefId::ModuleId(m) => Visibility::Module(m), |
87 | _ => { | 90 | _ => { |
88 | // error: visibility needs to refer to module | 91 | // error: visibility needs to refer to module |
89 | None | 92 | return None; |
90 | } | 93 | } |
91 | } | 94 | } |
92 | } | 95 | } |
93 | RawVisibility::Public => Some(Visibility::Public), | 96 | RawVisibility::Public => Visibility::Public, |
97 | }; | ||
98 | |||
99 | // In block expressions, `self` normally refers to the containing non-block module, and | ||
100 | // `super` to its parent (etc.). However, visibilities must only refer to a module in the | ||
101 | // DefMap they're written in, so we restrict them when that happens. | ||
102 | if let Visibility::Module(m) = vis { | ||
103 | if self.block_id() != m.block { | ||
104 | mark::hit!(adjust_vis_in_block_def_map); | ||
105 | vis = Visibility::Module(self.module_id(self.root())); | ||
106 | log::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis); | ||
107 | } | ||
94 | } | 108 | } |
109 | |||
110 | Some(vis) | ||
95 | } | 111 | } |
96 | 112 | ||
97 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change | 113 | // Returns Yes if we are sure that additions to `ItemMap` wouldn't change |
@@ -100,30 +116,69 @@ impl CrateDefMap { | |||
100 | &self, | 116 | &self, |
101 | db: &dyn DefDatabase, | 117 | db: &dyn DefDatabase, |
102 | mode: ResolveMode, | 118 | mode: ResolveMode, |
119 | mut original_module: LocalModuleId, | ||
120 | path: &ModPath, | ||
121 | shadow: BuiltinShadowMode, | ||
122 | ) -> ResolvePathResult { | ||
123 | let mut result = ResolvePathResult::empty(ReachedFixedPoint::No); | ||
124 | |||
125 | let mut arc; | ||
126 | let mut current_map = self; | ||
127 | loop { | ||
128 | let new = current_map.resolve_path_fp_with_macro_single( | ||
129 | db, | ||
130 | mode, | ||
131 | original_module, | ||
132 | path, | ||
133 | shadow, | ||
134 | ); | ||
135 | |||
136 | // Merge `new` into `result`. | ||
137 | result.resolved_def = result.resolved_def.or(new.resolved_def); | ||
138 | if result.reached_fixedpoint == ReachedFixedPoint::No { | ||
139 | result.reached_fixedpoint = new.reached_fixedpoint; | ||
140 | } | ||
141 | // FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates? | ||
142 | result.krate = result.krate.or(new.krate); | ||
143 | result.segment_index = match (result.segment_index, new.segment_index) { | ||
144 | (Some(idx), None) => Some(idx), | ||
145 | (Some(old), Some(new)) => Some(old.max(new)), | ||
146 | (None, new) => new, | ||
147 | }; | ||
148 | |||
149 | match ¤t_map.block { | ||
150 | Some(block) => { | ||
151 | original_module = block.parent.local_id; | ||
152 | arc = block.parent.def_map(db); | ||
153 | current_map = &*arc; | ||
154 | } | ||
155 | None => return result, | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | |||
160 | pub(super) fn resolve_path_fp_with_macro_single( | ||
161 | &self, | ||
162 | db: &dyn DefDatabase, | ||
163 | mode: ResolveMode, | ||
103 | original_module: LocalModuleId, | 164 | original_module: LocalModuleId, |
104 | path: &ModPath, | 165 | path: &ModPath, |
105 | shadow: BuiltinShadowMode, | 166 | shadow: BuiltinShadowMode, |
106 | ) -> ResolvePathResult { | 167 | ) -> ResolvePathResult { |
107 | let mut segments = path.segments.iter().enumerate(); | 168 | let mut segments = path.segments().iter().enumerate(); |
108 | let mut curr_per_ns: PerNs = match path.kind { | 169 | let mut curr_per_ns: PerNs = match path.kind { |
109 | PathKind::DollarCrate(krate) => { | 170 | PathKind::DollarCrate(krate) => { |
110 | if krate == self.krate { | 171 | if krate == self.krate { |
111 | mark::hit!(macro_dollar_crate_self); | 172 | mark::hit!(macro_dollar_crate_self); |
112 | PerNs::types( | 173 | PerNs::types(self.crate_root(db).into(), Visibility::Public) |
113 | ModuleId { krate: self.krate, local_id: self.root }.into(), | ||
114 | Visibility::Public, | ||
115 | ) | ||
116 | } else { | 174 | } else { |
117 | let def_map = db.crate_def_map(krate); | 175 | let def_map = db.crate_def_map(krate); |
118 | let module = ModuleId { krate, local_id: def_map.root }; | 176 | let module = def_map.module_id(def_map.root); |
119 | mark::hit!(macro_dollar_crate_other); | 177 | mark::hit!(macro_dollar_crate_other); |
120 | PerNs::types(module.into(), Visibility::Public) | 178 | PerNs::types(module.into(), Visibility::Public) |
121 | } | 179 | } |
122 | } | 180 | } |
123 | PathKind::Crate => PerNs::types( | 181 | PathKind::Crate => PerNs::types(self.crate_root(db).into(), Visibility::Public), |
124 | ModuleId { krate: self.krate, local_id: self.root }.into(), | ||
125 | Visibility::Public, | ||
126 | ), | ||
127 | // plain import or absolute path in 2015: crate-relative with | 182 | // plain import or absolute path in 2015: crate-relative with |
128 | // fallback to extern prelude (with the simplification in | 183 | // fallback to extern prelude (with the simplification in |
129 | // rust-lang/rust#57745) | 184 | // rust-lang/rust#57745) |
@@ -151,23 +206,49 @@ impl CrateDefMap { | |||
151 | // BuiltinShadowMode wasn't Module, then we need to try | 206 | // BuiltinShadowMode wasn't Module, then we need to try |
152 | // resolving it as a builtin. | 207 | // resolving it as a builtin. |
153 | let prefer_module = | 208 | let prefer_module = |
154 | if path.segments.len() == 1 { shadow } else { BuiltinShadowMode::Module }; | 209 | if path.segments().len() == 1 { shadow } else { BuiltinShadowMode::Module }; |
155 | 210 | ||
156 | log::debug!("resolving {:?} in module", segment); | 211 | log::debug!("resolving {:?} in module", segment); |
157 | self.resolve_name_in_module(db, original_module, &segment, prefer_module) | 212 | self.resolve_name_in_module(db, original_module, &segment, prefer_module) |
158 | } | 213 | } |
159 | PathKind::Super(lvl) => { | 214 | PathKind::Super(lvl) => { |
160 | let m = successors(Some(original_module), |m| self.modules[*m].parent) | 215 | let mut module = original_module; |
161 | .nth(lvl as usize); | 216 | for i in 0..lvl { |
162 | if let Some(local_id) = m { | 217 | match self.modules[module].parent { |
163 | PerNs::types( | 218 | Some(it) => module = it, |
164 | ModuleId { krate: self.krate, local_id }.into(), | 219 | None => match &self.block { |
165 | Visibility::Public, | 220 | Some(block) => { |
166 | ) | 221 | // Look up remaining path in parent `DefMap` |
167 | } else { | 222 | let new_path = ModPath::from_segments( |
168 | log::debug!("super path in root module"); | 223 | PathKind::Super(lvl - i), |
169 | return ResolvePathResult::empty(ReachedFixedPoint::Yes); | 224 | path.segments().to_vec(), |
225 | ); | ||
226 | log::debug!("`super` path: {} -> {} in parent map", path, new_path); | ||
227 | return block.parent.def_map(db).resolve_path_fp_with_macro( | ||
228 | db, | ||
229 | mode, | ||
230 | block.parent.local_id, | ||
231 | &new_path, | ||
232 | shadow, | ||
233 | ); | ||
234 | } | ||
235 | None => { | ||
236 | log::debug!("super path in root module"); | ||
237 | return ResolvePathResult::empty(ReachedFixedPoint::Yes); | ||
238 | } | ||
239 | }, | ||
240 | } | ||
170 | } | 241 | } |
242 | |||
243 | // Resolve `self` to the containing crate-rooted module if we're a block | ||
244 | self.with_ancestor_maps(db, module, &mut |def_map, module| { | ||
245 | if def_map.block.is_some() { | ||
246 | None // keep ascending | ||
247 | } else { | ||
248 | Some(PerNs::types(def_map.module_id(module).into(), Visibility::Public)) | ||
249 | } | ||
250 | }) | ||
251 | .expect("block DefMap not rooted in crate DefMap") | ||
171 | } | 252 | } |
172 | PathKind::Abs => { | 253 | PathKind::Abs => { |
173 | // 2018-style absolute path -- only extern prelude | 254 | // 2018-style absolute path -- only extern prelude |
@@ -201,12 +282,12 @@ impl CrateDefMap { | |||
201 | curr_per_ns = match curr { | 282 | curr_per_ns = match curr { |
202 | ModuleDefId::ModuleId(module) => { | 283 | ModuleDefId::ModuleId(module) => { |
203 | if module.krate != self.krate { | 284 | if module.krate != self.krate { |
204 | let path = ModPath { | 285 | let path = ModPath::from_segments( |
205 | segments: path.segments[i..].to_vec(), | 286 | PathKind::Super(0), |
206 | kind: PathKind::Super(0), | 287 | path.segments()[i..].iter().cloned(), |
207 | }; | 288 | ); |
208 | log::debug!("resolving {:?} in other crate", path); | 289 | log::debug!("resolving {:?} in other crate", path); |
209 | let defp_map = db.crate_def_map(module.krate); | 290 | let defp_map = module.def_map(db); |
210 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); | 291 | let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); |
211 | return ResolvePathResult::with( | 292 | return ResolvePathResult::with( |
212 | def, | 293 | def, |
@@ -216,8 +297,16 @@ impl CrateDefMap { | |||
216 | ); | 297 | ); |
217 | } | 298 | } |
218 | 299 | ||
300 | let def_map; | ||
301 | let module_data = if module.block == self.block_id() { | ||
302 | &self[module.local_id] | ||
303 | } else { | ||
304 | def_map = module.def_map(db); | ||
305 | &def_map[module.local_id] | ||
306 | }; | ||
307 | |||
219 | // Since it is a qualified path here, it should not contains legacy macros | 308 | // Since it is a qualified path here, it should not contains legacy macros |
220 | self[module.local_id].scope.get(&segment) | 309 | module_data.scope.get(&segment) |
221 | } | 310 | } |
222 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { | 311 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { |
223 | // enum variant | 312 | // enum variant |
@@ -319,7 +408,7 @@ impl CrateDefMap { | |||
319 | self | 408 | self |
320 | } else { | 409 | } else { |
321 | // Extend lifetime | 410 | // Extend lifetime |
322 | keep = db.crate_def_map(prelude.krate); | 411 | keep = prelude.def_map(db); |
323 | &keep | 412 | &keep |
324 | }; | 413 | }; |
325 | def_map[prelude.local_id].scope.get(name) | 414 | def_map[prelude.local_id].scope.get(name) |
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index c459fa66d..bd3e2701b 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs | |||
@@ -11,17 +11,24 @@ use base_db::{fixture::WithFixture, SourceDatabase}; | |||
11 | use expect_test::{expect, Expect}; | 11 | use expect_test::{expect, Expect}; |
12 | use test_utils::mark; | 12 | use test_utils::mark; |
13 | 13 | ||
14 | use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; | 14 | use crate::{db::DefDatabase, test_db::TestDB}; |
15 | 15 | ||
16 | fn compute_crate_def_map(ra_fixture: &str) -> Arc<CrateDefMap> { | 16 | use super::DefMap; |
17 | |||
18 | fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> { | ||
17 | let db = TestDB::with_files(ra_fixture); | 19 | let db = TestDB::with_files(ra_fixture); |
18 | let krate = db.crate_graph().iter().next().unwrap(); | 20 | let krate = db.crate_graph().iter().next().unwrap(); |
19 | db.crate_def_map(krate) | 21 | db.crate_def_map(krate) |
20 | } | 22 | } |
21 | 23 | ||
24 | fn render_crate_def_map(ra_fixture: &str) -> String { | ||
25 | let db = TestDB::with_files(ra_fixture); | ||
26 | let krate = db.crate_graph().iter().next().unwrap(); | ||
27 | db.crate_def_map(krate).dump(&db) | ||
28 | } | ||
29 | |||
22 | fn check(ra_fixture: &str, expect: Expect) { | 30 | fn check(ra_fixture: &str, expect: Expect) { |
23 | let def_map = compute_crate_def_map(ra_fixture); | 31 | let actual = render_crate_def_map(ra_fixture); |
24 | let actual = def_map.dump(); | ||
25 | expect.assert_eq(&actual); | 32 | expect.assert_eq(&actual); |
26 | } | 33 | } |
27 | 34 | ||
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index 58d69d3c6..e8e72e5ef 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -62,6 +62,22 @@ fn unresolved_extern_crate() { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | #[test] | 64 | #[test] |
65 | fn extern_crate_self_as() { | ||
66 | mark::check!(extern_crate_self_as); | ||
67 | check_diagnostics( | ||
68 | r" | ||
69 | //- /lib.rs | ||
70 | extern crate doesnotexist; | ||
71 | //^^^^^^^^^^^^^^^^^^^^^^^^^^ unresolved extern crate | ||
72 | // Should not error. | ||
73 | extern crate self as foo; | ||
74 | struct Foo; | ||
75 | use foo::Foo as Bar; | ||
76 | ", | ||
77 | ); | ||
78 | } | ||
79 | |||
80 | #[test] | ||
65 | fn dedup_unresolved_import_from_unresolved_crate() { | 81 | fn dedup_unresolved_import_from_unresolved_crate() { |
66 | check_diagnostics( | 82 | check_diagnostics( |
67 | r" | 83 | r" |
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs index e5e9e8ca1..36ed5e8ce 100644 --- a/crates/hir_def/src/nameres/tests/macros.rs +++ b/crates/hir_def/src/nameres/tests/macros.rs | |||
@@ -391,11 +391,21 @@ foo!(ok_shadow); | |||
391 | mod m4; | 391 | mod m4; |
392 | bar!(OkMacroUse); | 392 | bar!(OkMacroUse); |
393 | 393 | ||
394 | mod m5; | ||
395 | baz!(OkMacroUseInner); | ||
396 | |||
394 | //- /m3/m4.rs | 397 | //- /m3/m4.rs |
395 | foo!(ok_shadow_deep); | 398 | foo!(ok_shadow_deep); |
396 | macro_rules! bar { | 399 | macro_rules! bar { |
397 | ($x:ident) => { struct $x; } | 400 | ($x:ident) => { struct $x; } |
398 | } | 401 | } |
402 | //- /m3/m5.rs | ||
403 | #![macro_use] | ||
404 | macro_rules! baz { | ||
405 | ($x:ident) => { struct $x; } | ||
406 | } | ||
407 | |||
408 | |||
399 | "#, | 409 | "#, |
400 | expect![[r#" | 410 | expect![[r#" |
401 | crate | 411 | crate |
@@ -423,11 +433,15 @@ macro_rules! bar { | |||
423 | crate::m3 | 433 | crate::m3 |
424 | OkAfterInside: t v | 434 | OkAfterInside: t v |
425 | OkMacroUse: t v | 435 | OkMacroUse: t v |
436 | OkMacroUseInner: t v | ||
426 | m4: t | 437 | m4: t |
438 | m5: t | ||
427 | ok_shadow: v | 439 | ok_shadow: v |
428 | 440 | ||
429 | crate::m3::m4 | 441 | crate::m3::m4 |
430 | ok_shadow_deep: v | 442 | ok_shadow_deep: v |
443 | |||
444 | crate::m3::m5 | ||
431 | "#]], | 445 | "#]], |
432 | ); | 446 | ); |
433 | } | 447 | } |