diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 58 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests.rs | 19 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/diagnostics.rs | 19 |
3 files changed, 68 insertions, 28 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 81cf652b0..d0fefb5af 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -242,7 +242,7 @@ struct DefCollector<'a> { | |||
242 | impl DefCollector<'_> { | 242 | impl DefCollector<'_> { |
243 | fn seed_with_top_level(&mut self) { | 243 | fn seed_with_top_level(&mut self) { |
244 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; | 244 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; |
245 | let item_tree = self.db.item_tree(file_id.into()); | 245 | let item_tree = self.db.file_item_tree(file_id.into()); |
246 | let module_id = self.def_map.root; | 246 | let module_id = self.def_map.root; |
247 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; | 247 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; |
248 | if item_tree | 248 | if item_tree |
@@ -263,7 +263,7 @@ impl DefCollector<'_> { | |||
263 | } | 263 | } |
264 | 264 | ||
265 | fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) { | 265 | fn seed_with_inner(&mut self, block: AstId<ast::BlockExpr>) { |
266 | let item_tree = self.db.item_tree(block.file_id); | 266 | let item_tree = self.db.file_item_tree(block.file_id); |
267 | let module_id = self.def_map.root; | 267 | let module_id = self.def_map.root; |
268 | self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block }; | 268 | self.def_map.modules[module_id].origin = ModuleOrigin::BlockExpr { block }; |
269 | if item_tree | 269 | if item_tree |
@@ -656,26 +656,28 @@ impl DefCollector<'_> { | |||
656 | } | 656 | } |
657 | } | 657 | } |
658 | } else { | 658 | } else { |
659 | match import.path.segments().last() { | 659 | let name = match &import.alias { |
660 | Some(last_segment) => { | 660 | Some(ImportAlias::Alias(name)) => Some(name.clone()), |
661 | let name = match &import.alias { | 661 | Some(ImportAlias::Underscore) => None, |
662 | Some(ImportAlias::Alias(name)) => Some(name.clone()), | 662 | None => match import.path.segments().last() { |
663 | Some(ImportAlias::Underscore) => None, | 663 | Some(last_segment) => Some(last_segment.clone()), |
664 | None => Some(last_segment.clone()), | 664 | None => { |
665 | }; | 665 | cov_mark::hit!(bogus_paths); |
666 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); | 666 | return; |
667 | |||
668 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 | ||
669 | if import.is_extern_crate && module_id == self.def_map.root { | ||
670 | if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) { | ||
671 | self.def_map.extern_prelude.insert(name.clone(), def); | ||
672 | } | ||
673 | } | 667 | } |
668 | }, | ||
669 | }; | ||
670 | |||
671 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); | ||
674 | 672 | ||
675 | self.update(module_id, &[(name, def)], vis, ImportType::Named); | 673 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 |
674 | if import.is_extern_crate && module_id == self.def_map.root { | ||
675 | if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) { | ||
676 | self.def_map.extern_prelude.insert(name.clone(), def); | ||
676 | } | 677 | } |
677 | None => cov_mark::hit!(bogus_paths), | ||
678 | } | 678 | } |
679 | |||
680 | self.update(module_id, &[(name, def)], vis, ImportType::Named); | ||
679 | } | 681 | } |
680 | } | 682 | } |
681 | 683 | ||
@@ -893,7 +895,7 @@ impl DefCollector<'_> { | |||
893 | } | 895 | } |
894 | 896 | ||
895 | // Then, fetch and process the item tree. This will reuse the expansion result from above. | 897 | // Then, fetch and process the item tree. This will reuse the expansion result from above. |
896 | let item_tree = self.db.item_tree(file_id); | 898 | let item_tree = self.db.file_item_tree(file_id); |
897 | let mod_dir = self.mod_dirs[&module_id].clone(); | 899 | let mod_dir = self.mod_dirs[&module_id].clone(); |
898 | ModCollector { | 900 | ModCollector { |
899 | def_collector: &mut *self, | 901 | def_collector: &mut *self, |
@@ -949,21 +951,21 @@ impl DefCollector<'_> { | |||
949 | let mut diagnosed_extern_crates = FxHashSet::default(); | 951 | let mut diagnosed_extern_crates = FxHashSet::default(); |
950 | for directive in &self.unresolved_imports { | 952 | for directive in &self.unresolved_imports { |
951 | if let ImportSource::ExternCrate(krate) = directive.import.source { | 953 | if let ImportSource::ExternCrate(krate) = directive.import.source { |
952 | let item_tree = self.db.item_tree(krate.file_id); | 954 | let item_tree = krate.item_tree(self.db); |
953 | let extern_crate = &item_tree[krate.value]; | 955 | let extern_crate = &item_tree[krate.value]; |
954 | 956 | ||
955 | diagnosed_extern_crates.insert(extern_crate.name.clone()); | 957 | diagnosed_extern_crates.insert(extern_crate.name.clone()); |
956 | 958 | ||
957 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate( | 959 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate( |
958 | directive.module_id, | 960 | directive.module_id, |
959 | InFile::new(krate.file_id, extern_crate.ast_id), | 961 | InFile::new(krate.file_id(), extern_crate.ast_id), |
960 | )); | 962 | )); |
961 | } | 963 | } |
962 | } | 964 | } |
963 | 965 | ||
964 | for directive in &self.unresolved_imports { | 966 | for directive in &self.unresolved_imports { |
965 | if let ImportSource::Import(import) = &directive.import.source { | 967 | if let ImportSource::Import(import) = &directive.import.source { |
966 | let item_tree = self.db.item_tree(import.file_id); | 968 | let item_tree = import.item_tree(self.db); |
967 | let import_data = &item_tree[import.value]; | 969 | let import_data = &item_tree[import.value]; |
968 | 970 | ||
969 | match (import_data.path.segments().first(), &import_data.path.kind) { | 971 | match (import_data.path.segments().first(), &import_data.path.kind) { |
@@ -977,7 +979,7 @@ impl DefCollector<'_> { | |||
977 | 979 | ||
978 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( | 980 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_import( |
979 | directive.module_id, | 981 | directive.module_id, |
980 | InFile::new(import.file_id, import_data.ast_id), | 982 | InFile::new(import.file_id(), import_data.ast_id), |
981 | import_data.index, | 983 | import_data.index, |
982 | )); | 984 | )); |
983 | } | 985 | } |
@@ -1053,7 +1055,7 @@ impl ModCollector<'_, '_> { | |||
1053 | self.def_collector.db, | 1055 | self.def_collector.db, |
1054 | krate, | 1056 | krate, |
1055 | &self.item_tree, | 1057 | &self.item_tree, |
1056 | InFile::new(self.file_id, import_id), | 1058 | ItemTreeId::new(self.file_id, import_id), |
1057 | ), | 1059 | ), |
1058 | status: PartialResolvedImport::Unresolved, | 1060 | status: PartialResolvedImport::Unresolved, |
1059 | }) | 1061 | }) |
@@ -1065,7 +1067,7 @@ impl ModCollector<'_, '_> { | |||
1065 | self.def_collector.db, | 1067 | self.def_collector.db, |
1066 | krate, | 1068 | krate, |
1067 | &self.item_tree, | 1069 | &self.item_tree, |
1068 | InFile::new(self.file_id, import_id), | 1070 | ItemTreeId::new(self.file_id, import_id), |
1069 | ), | 1071 | ), |
1070 | status: PartialResolvedImport::Unresolved, | 1072 | status: PartialResolvedImport::Unresolved, |
1071 | }) | 1073 | }) |
@@ -1297,7 +1299,7 @@ impl ModCollector<'_, '_> { | |||
1297 | Some((file_id, is_mod_rs)), | 1299 | Some((file_id, is_mod_rs)), |
1298 | &self.item_tree[module.visibility], | 1300 | &self.item_tree[module.visibility], |
1299 | ); | 1301 | ); |
1300 | let item_tree = db.item_tree(file_id.into()); | 1302 | let item_tree = db.file_item_tree(file_id.into()); |
1301 | ModCollector { | 1303 | ModCollector { |
1302 | def_collector: &mut *self.def_collector, | 1304 | def_collector: &mut *self.def_collector, |
1303 | macro_depth: self.macro_depth, | 1305 | macro_depth: self.macro_depth, |
@@ -1469,7 +1471,9 @@ impl ModCollector<'_, '_> { | |||
1469 | ) | 1471 | ) |
1470 | }) | 1472 | }) |
1471 | }, | 1473 | }, |
1472 | &mut |err| error = Some(err), | 1474 | &mut |err| { |
1475 | error.get_or_insert(err); | ||
1476 | }, | ||
1473 | ) { | 1477 | ) { |
1474 | Ok(Ok(macro_call_id)) => { | 1478 | Ok(Ok(macro_call_id)) => { |
1475 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1479 | self.def_collector.unexpanded_macros.push(MacroDirective { |
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs index de3aa4f9a..4f2e7a2f9 100644 --- a/crates/hir_def/src/nameres/tests.rs +++ b/crates/hir_def/src/nameres/tests.rs | |||
@@ -713,3 +713,22 @@ pub fn f() {} | |||
713 | "#]], | 713 | "#]], |
714 | ); | 714 | ); |
715 | } | 715 | } |
716 | |||
717 | #[test] | ||
718 | fn use_crate_as() { | ||
719 | check( | ||
720 | r#" | ||
721 | use crate as foo; | ||
722 | |||
723 | use foo::bar as baz; | ||
724 | |||
725 | fn bar() {} | ||
726 | "#, | ||
727 | expect![[r#" | ||
728 | crate | ||
729 | bar: v | ||
730 | baz: v | ||
731 | foo: t | ||
732 | "#]], | ||
733 | ); | ||
734 | } | ||
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index c22ef46fd..a89061c2e 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -196,7 +196,24 @@ fn builtin_macro_fails_expansion() { | |||
196 | macro_rules! include { () => {} } | 196 | macro_rules! include { () => {} } |
197 | 197 | ||
198 | include!("doesntexist"); | 198 | include!("doesntexist"); |
199 | //^^^^^^^^^^^^^^^^^^^^^^^^ could not convert tokens | 199 | //^^^^^^^^^^^^^^^^^^^^^^^^ failed to load file `doesntexist` |
200 | "#, | ||
201 | ); | ||
202 | } | ||
203 | |||
204 | #[test] | ||
205 | fn good_out_dir_diagnostic() { | ||
206 | check_diagnostics( | ||
207 | r#" | ||
208 | #[rustc_builtin_macro] | ||
209 | macro_rules! include { () => {} } | ||
210 | #[rustc_builtin_macro] | ||
211 | macro_rules! env { () => {} } | ||
212 | #[rustc_builtin_macro] | ||
213 | macro_rules! concat { () => {} } | ||
214 | |||
215 | include!(concat!(env!("OUT_DIR"), "/out.rs")); | ||
216 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix | ||
200 | "#, | 217 | "#, |
201 | ); | 218 | ); |
202 | } | 219 | } |