aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-09-16 14:47:58 +0100
committerJonas Schievink <[email protected]>2020-09-16 16:26:51 +0100
commit4785162b080acf3b5e711f49b2df399b11ee5cb0 (patch)
tree16be6d4263e49a13c583c4276f112c3c284992fc
parent4ac9a2e5d3c43401450b812786ab1551d535420c (diff)
Track import sources and emit diagnostics
-rw-r--r--crates/hir_def/src/nameres/collector.rs61
-rw-r--r--crates/hir_def/src/nameres/tests/mod_resolution.rs20
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
6use base_db::{CrateId, FileId, ProcMacroId}; 6use base_db::{CrateId, FileId, ProcMacroId};
7use cfg::CfgOptions; 7use cfg::CfgOptions;
8use hir_expand::InFile;
8use hir_expand::{ 9use 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)]
114enum ImportSource {
115 Import(ItemTreeId<item_tree::Import>),
116 ExternCrate(ItemTreeId<item_tree::ExternCrate>),
117}
118
119#[derive(Clone, Debug, Eq, PartialEq)]
115struct Import { 120struct 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
125impl Import { 131impl 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 "#]]