diff options
author | Jonas Schievink <[email protected]> | 2020-09-16 14:47:58 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-09-16 16:26:51 +0100 |
commit | 4785162b080acf3b5e711f49b2df399b11ee5cb0 (patch) | |
tree | 16be6d4263e49a13c583c4276f112c3c284992fc | |
parent | 4ac9a2e5d3c43401450b812786ab1551d535420c (diff) |
Track import sources and emit diagnostics
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 61 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/mod_resolution.rs | 20 |
2 files changed, 60 insertions, 21 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 952a04b35..deb3885f9 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | use base_db::{CrateId, FileId, ProcMacroId}; | 6 | use base_db::{CrateId, FileId, ProcMacroId}; |
7 | use cfg::CfgOptions; | 7 | use cfg::CfgOptions; |
8 | use hir_expand::InFile; | ||
8 | use hir_expand::{ | 9 | use hir_expand::{ |
9 | ast_id_map::FileAstId, | 10 | ast_id_map::FileAstId, |
10 | builtin_derive::find_builtin_derive, | 11 | builtin_derive::find_builtin_derive, |
@@ -21,9 +22,7 @@ use crate::{ | |||
21 | attr::Attrs, | 22 | attr::Attrs, |
22 | db::DefDatabase, | 23 | db::DefDatabase, |
23 | item_scope::{ImportType, PerNsGlobImports}, | 24 | item_scope::{ImportType, PerNsGlobImports}, |
24 | item_tree::{ | 25 | item_tree::{self, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind}, |
25 | self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind, | ||
26 | }, | ||
27 | nameres::{ | 26 | nameres::{ |
28 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, | 27 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, |
29 | BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, | 28 | BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, |
@@ -112,6 +111,12 @@ impl PartialResolvedImport { | |||
112 | } | 111 | } |
113 | 112 | ||
114 | #[derive(Clone, Debug, Eq, PartialEq)] | 113 | #[derive(Clone, Debug, Eq, PartialEq)] |
114 | enum ImportSource { | ||
115 | Import(ItemTreeId<item_tree::Import>), | ||
116 | ExternCrate(ItemTreeId<item_tree::ExternCrate>), | ||
117 | } | ||
118 | |||
119 | #[derive(Clone, Debug, Eq, PartialEq)] | ||
115 | struct Import { | 120 | struct Import { |
116 | pub path: ModPath, | 121 | pub path: ModPath, |
117 | pub alias: Option<ImportAlias>, | 122 | pub alias: Option<ImportAlias>, |
@@ -120,11 +125,12 @@ struct Import { | |||
120 | pub is_prelude: bool, | 125 | pub is_prelude: bool, |
121 | pub is_extern_crate: bool, | 126 | pub is_extern_crate: bool, |
122 | pub is_macro_use: bool, | 127 | pub is_macro_use: bool, |
128 | source: ImportSource, | ||
123 | } | 129 | } |
124 | 130 | ||
125 | impl Import { | 131 | impl Import { |
126 | fn from_use(tree: &ItemTree, id: FileItemTreeId<item_tree::Import>) -> Self { | 132 | fn from_use(tree: &ItemTree, id: ItemTreeId<item_tree::Import>) -> Self { |
127 | let it = &tree[id]; | 133 | let it = &tree[id.value]; |
128 | let visibility = &tree[it.visibility]; | 134 | let visibility = &tree[it.visibility]; |
129 | Self { | 135 | Self { |
130 | path: it.path.clone(), | 136 | path: it.path.clone(), |
@@ -134,11 +140,12 @@ impl Import { | |||
134 | is_prelude: it.is_prelude, | 140 | is_prelude: it.is_prelude, |
135 | is_extern_crate: false, | 141 | is_extern_crate: false, |
136 | is_macro_use: false, | 142 | is_macro_use: false, |
143 | source: ImportSource::Import(id), | ||
137 | } | 144 | } |
138 | } | 145 | } |
139 | 146 | ||
140 | fn from_extern_crate(tree: &ItemTree, id: FileItemTreeId<item_tree::ExternCrate>) -> Self { | 147 | fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) -> Self { |
141 | let it = &tree[id]; | 148 | let it = &tree[id.value]; |
142 | let visibility = &tree[it.visibility]; | 149 | let visibility = &tree[it.visibility]; |
143 | Self { | 150 | Self { |
144 | path: it.path.clone(), | 151 | path: it.path.clone(), |
@@ -148,6 +155,7 @@ impl Import { | |||
148 | is_prelude: false, | 155 | is_prelude: false, |
149 | is_extern_crate: true, | 156 | is_extern_crate: true, |
150 | is_macro_use: it.is_macro_use, | 157 | is_macro_use: it.is_macro_use, |
158 | source: ImportSource::ExternCrate(id), | ||
151 | } | 159 | } |
152 | } | 160 | } |
153 | } | 161 | } |
@@ -245,9 +253,10 @@ impl DefCollector<'_> { | |||
245 | 253 | ||
246 | let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); | 254 | let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); |
247 | // show unresolved imports in completion, etc | 255 | // show unresolved imports in completion, etc |
248 | for directive in unresolved_imports { | 256 | for directive in &unresolved_imports { |
249 | self.record_resolved_import(&directive) | 257 | self.record_resolved_import(directive) |
250 | } | 258 | } |
259 | self.unresolved_imports = unresolved_imports; | ||
251 | 260 | ||
252 | // Record proc-macros | 261 | // Record proc-macros |
253 | self.collect_proc_macro(); | 262 | self.collect_proc_macro(); |
@@ -778,7 +787,29 @@ impl DefCollector<'_> { | |||
778 | .collect(item_tree.top_level_items()); | 787 | .collect(item_tree.top_level_items()); |
779 | } | 788 | } |
780 | 789 | ||
781 | fn finish(self) -> CrateDefMap { | 790 | fn finish(mut self) -> CrateDefMap { |
791 | for directive in &self.unresolved_imports { | ||
792 | match directive.import.source { | ||
793 | ImportSource::Import(import) => { | ||
794 | let item_tree = self.db.item_tree(import.file_id); | ||
795 | let import_data = &item_tree[import.value]; | ||
796 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( | ||
797 | directive.module_id, | ||
798 | InFile::new(import.file_id, import_data.ast_id), | ||
799 | import_data.index, | ||
800 | )); | ||
801 | } | ||
802 | ImportSource::ExternCrate(krate) => { | ||
803 | let item_tree = self.db.item_tree(krate.file_id); | ||
804 | let extern_crate = &item_tree[krate.value]; | ||
805 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate( | ||
806 | directive.module_id, | ||
807 | InFile::new(krate.file_id, extern_crate.ast_id), | ||
808 | )); | ||
809 | } | ||
810 | } | ||
811 | } | ||
812 | |||
782 | self.def_map | 813 | self.def_map |
783 | } | 814 | } |
784 | } | 815 | } |
@@ -834,14 +865,20 @@ impl ModCollector<'_, '_> { | |||
834 | ModItem::Import(import_id) => { | 865 | ModItem::Import(import_id) => { |
835 | self.def_collector.unresolved_imports.push(ImportDirective { | 866 | self.def_collector.unresolved_imports.push(ImportDirective { |
836 | module_id: self.module_id, | 867 | module_id: self.module_id, |
837 | import: Import::from_use(&self.item_tree, import_id), | 868 | import: Import::from_use( |
869 | &self.item_tree, | ||
870 | InFile::new(self.file_id, import_id), | ||
871 | ), | ||
838 | status: PartialResolvedImport::Unresolved, | 872 | status: PartialResolvedImport::Unresolved, |
839 | }) | 873 | }) |
840 | } | 874 | } |
841 | ModItem::ExternCrate(import_id) => { | 875 | ModItem::ExternCrate(import_id) => { |
842 | self.def_collector.unresolved_imports.push(ImportDirective { | 876 | self.def_collector.unresolved_imports.push(ImportDirective { |
843 | module_id: self.module_id, | 877 | module_id: self.module_id, |
844 | import: Import::from_extern_crate(&self.item_tree, import_id), | 878 | import: Import::from_extern_crate( |
879 | &self.item_tree, | ||
880 | InFile::new(self.file_id, import_id), | ||
881 | ), | ||
845 | status: PartialResolvedImport::Unresolved, | 882 | status: PartialResolvedImport::Unresolved, |
846 | }) | 883 | }) |
847 | } | 884 | } |
diff --git a/crates/hir_def/src/nameres/tests/mod_resolution.rs b/crates/hir_def/src/nameres/tests/mod_resolution.rs index 1f619787e..3b9f79544 100644 --- a/crates/hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/hir_def/src/nameres/tests/mod_resolution.rs | |||
@@ -688,19 +688,21 @@ fn unresolved_module_diagnostics() { | |||
688 | 688 | ||
689 | expect![[r#" | 689 | expect![[r#" |
690 | [ | 690 | [ |
691 | UnresolvedModule { | 691 | DefDiagnostic { |
692 | module: Idx::<ModuleData>(0), | 692 | in_module: Idx::<ModuleData>(0), |
693 | declaration: InFile { | 693 | kind: UnresolvedModule { |
694 | file_id: HirFileId( | 694 | declaration: InFile { |
695 | FileId( | 695 | file_id: HirFileId( |
696 | FileId( | 696 | FileId( |
697 | 0, | 697 | FileId( |
698 | 0, | ||
699 | ), | ||
698 | ), | 700 | ), |
699 | ), | 701 | ), |
700 | ), | 702 | value: FileAstId::<syntax::ast::generated::nodes::Module>(1), |
701 | value: FileAstId::<syntax::ast::generated::nodes::Module>(1), | 703 | }, |
704 | candidate: "bar.rs", | ||
702 | }, | 705 | }, |
703 | candidate: "bar.rs", | ||
704 | }, | 706 | }, |
705 | ] | 707 | ] |
706 | "#]] | 708 | "#]] |