aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2021-01-03 10:08:08 +0000
committerKirill Bulatov <[email protected]>2021-01-04 15:44:27 +0000
commitd27dea86b7dd4123f75ad176037b3c754eddfa65 (patch)
treeae11b6934630892583ea68031536d1d590f2b06e /crates/hir_def
parent63d83fa38584fa0537f896bee5d90709c1352030 (diff)
Properly check assoc items lookup
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/import_map.rs105
-rw-r--r--crates/hir_def/src/item_scope.rs14
2 files changed, 73 insertions, 46 deletions
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 6283c1f1a..0ba8198b5 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -428,9 +428,8 @@ fn item_import_kind(item: ItemInNs) -> Option<ImportKind> {
428mod tests { 428mod tests {
429 use base_db::{fixture::WithFixture, SourceDatabase, Upcast}; 429 use base_db::{fixture::WithFixture, SourceDatabase, Upcast};
430 use expect_test::{expect, Expect}; 430 use expect_test::{expect, Expect};
431 use stdx::format_to;
432 431
433 use crate::{data::FunctionData, test_db::TestDB, AssocContainerId, Lookup}; 432 use crate::{test_db::TestDB, AssocContainerId, Lookup};
434 433
435 use super::*; 434 use super::*;
436 435
@@ -447,46 +446,55 @@ mod tests {
447 446
448 let actual = search_dependencies(db.upcast(), krate, query) 447 let actual = search_dependencies(db.upcast(), krate, query)
449 .into_iter() 448 .into_iter()
450 .filter_map(|item| { 449 .filter_map(|dependency| {
451 let mark = match item { 450 let dependency_krate = dependency.krate(db.upcast())?;
452 ItemInNs::Types(ModuleDefId::FunctionId(_)) 451 let dependency_imports = db.import_map(dependency_krate);
453 | ItemInNs::Values(ModuleDefId::FunctionId(_)) => "f", 452
454 ItemInNs::Types(_) => "t", 453 let (path, mark) = match assoc_item_path(&db, &dependency_imports, dependency) {
455 ItemInNs::Values(_) => "v", 454 Some(assoc_item_path) => (assoc_item_path, "a"),
456 ItemInNs::Macros(_) => "m", 455 None => (
456 dependency_imports.path_of(dependency)?.to_string(),
457 match dependency {
458 ItemInNs::Types(_) => "t",
459 ItemInNs::Values(_) => "v",
460 ItemInNs::Macros(_) => "m",
461 },
462 ),
457 }; 463 };
458 item.krate(db.upcast()).map(|krate| { 464
459 let map = db.import_map(krate); 465 Some(format!(
460 466 "{}::{} ({})\n",
461 let path = match assoc_to_trait(&db, item) { 467 crate_graph[dependency_krate].display_name.as_ref()?,
462 Some(trait_) => { 468 path,
463 let mut full_path = map.path_of(trait_).unwrap().to_string(); 469 mark
464 if let ItemInNs::Types(ModuleDefId::FunctionId(function_id)) 470 ))
465 | ItemInNs::Values(ModuleDefId::FunctionId(function_id)) = item
466 {
467 format_to!(
468 full_path,
469 "::{}",
470 FunctionData::fn_data_query(&db, function_id).name,
471 );
472 }
473 full_path
474 }
475 None => map.path_of(item).unwrap().to_string(),
476 };
477
478 format!(
479 "{}::{} ({})\n",
480 crate_graph[krate].display_name.as_ref().unwrap(),
481 path,
482 mark
483 )
484 })
485 }) 471 })
486 .collect::<String>(); 472 .collect::<String>();
487 expect.assert_eq(&actual) 473 expect.assert_eq(&actual)
488 } 474 }
489 475
476 fn assoc_item_path(
477 db: &dyn DefDatabase,
478 dependency_imports: &ImportMap,
479 dependency: ItemInNs,
480 ) -> Option<String> {
481 let dependency_assoc_item_id = dependency.as_assoc_item_id()?;
482 let trait_ = assoc_to_trait(db, dependency)?;
483 if let ModuleDefId::TraitId(tr) = trait_.as_module_def_id()? {
484 let trait_data = db.trait_data(tr);
485 let assoc_item_name =
486 trait_data.items.iter().find_map(|(assoc_item_name, assoc_item_id)| {
487 if &dependency_assoc_item_id == assoc_item_id {
488 Some(assoc_item_name)
489 } else {
490 None
491 }
492 })?;
493 return Some(format!("{}::{}", dependency_imports.path_of(trait_)?, assoc_item_name));
494 }
495 None
496 }
497
490 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> Option<ItemInNs> { 498 fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> Option<ItemInNs> {
491 let assoc: AssocItemId = match item { 499 let assoc: AssocItemId = match item {
492 ItemInNs::Types(it) | ItemInNs::Values(it) => match it { 500 ItemInNs::Types(it) | ItemInNs::Values(it) => match it {
@@ -745,13 +753,17 @@ mod tests {
745 } 753 }
746 754
747 #[test] 755 #[test]
748 fn fuzzy_import_trait() { 756 fn fuzzy_import_trait_and_assoc_items() {
749 let ra_fixture = r#" 757 let ra_fixture = r#"
750 //- /main.rs crate:main deps:dep 758 //- /main.rs crate:main deps:dep
751 //- /dep.rs crate:dep 759 //- /dep.rs crate:dep
752 pub mod fmt { 760 pub mod fmt {
753 pub trait Display { 761 pub trait Display {
754 fn format(); 762 type FmtTypeAlias;
763 const FMT_CONST: bool;
764
765 fn format_function();
766 fn format_method(&self);
755 } 767 }
756 } 768 }
757 "#; 769 "#;
@@ -763,7 +775,10 @@ mod tests {
763 expect![[r#" 775 expect![[r#"
764 dep::fmt (t) 776 dep::fmt (t)
765 dep::fmt::Display (t) 777 dep::fmt::Display (t)
766 dep::fmt::Display::format (f) 778 dep::fmt::Display::FMT_CONST (a)
779 dep::fmt::Display::FmtTypeAlias (a)
780 dep::fmt::Display::format_function (a)
781 dep::fmt::Display::format_method (a)
767 "#]], 782 "#]],
768 ); 783 );
769 } 784 }
@@ -804,8 +819,8 @@ mod tests {
804 dep::Fmt (v) 819 dep::Fmt (v)
805 dep::Fmt (m) 820 dep::Fmt (m)
806 dep::fmt::Display (t) 821 dep::fmt::Display (t)
807 dep::fmt::Display::fmt (f) 822 dep::fmt::Display::fmt (a)
808 dep::format (f) 823 dep::format (v)
809 "#]], 824 "#]],
810 ); 825 );
811 826
@@ -818,7 +833,7 @@ mod tests {
818 dep::Fmt (t) 833 dep::Fmt (t)
819 dep::Fmt (v) 834 dep::Fmt (v)
820 dep::Fmt (m) 835 dep::Fmt (m)
821 dep::fmt::Display::fmt (f) 836 dep::fmt::Display::fmt (a)
822 "#]], 837 "#]],
823 ); 838 );
824 839
@@ -832,7 +847,7 @@ mod tests {
832 dep::Fmt (v) 847 dep::Fmt (v)
833 dep::Fmt (m) 848 dep::Fmt (m)
834 dep::fmt::Display (t) 849 dep::fmt::Display (t)
835 dep::fmt::Display::fmt (f) 850 dep::fmt::Display::fmt (a)
836 "#]], 851 "#]],
837 ); 852 );
838 } 853 }
@@ -873,7 +888,7 @@ mod tests {
873 dep::Fmt (v) 888 dep::Fmt (v)
874 dep::Fmt (m) 889 dep::Fmt (m)
875 dep::fmt::Display (t) 890 dep::fmt::Display (t)
876 dep::fmt::Display::fmt (f) 891 dep::fmt::Display::fmt (a)
877 "#]], 892 "#]],
878 ); 893 );
879 894
@@ -886,7 +901,7 @@ mod tests {
886 dep::Fmt (t) 901 dep::Fmt (t)
887 dep::Fmt (v) 902 dep::Fmt (v)
888 dep::Fmt (m) 903 dep::Fmt (m)
889 dep::fmt::Display::fmt (f) 904 dep::fmt::Display::fmt (a)
890 "#]], 905 "#]],
891 ); 906 );
892 } 907 }
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index 62ab3b2bd..4da1c3ab0 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -10,11 +10,11 @@ use once_cell::sync::Lazy;
10use rustc_hash::{FxHashMap, FxHashSet}; 10use rustc_hash::{FxHashMap, FxHashSet};
11use test_utils::mark; 11use test_utils::mark;
12 12
13use crate::ModuleId;
14use crate::{ 13use crate::{
15 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, 14 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId,
16 LocalModuleId, Lookup, MacroDefId, ModuleDefId, TraitId, 15 LocalModuleId, Lookup, MacroDefId, ModuleDefId, TraitId,
17}; 16};
17use crate::{AssocItemId, ModuleId};
18 18
19#[derive(Copy, Clone)] 19#[derive(Copy, Clone)]
20pub(crate) enum ImportType { 20pub(crate) enum ImportType {
@@ -349,6 +349,18 @@ impl ItemInNs {
349 } 349 }
350 } 350 }
351 351
352 pub fn as_assoc_item_id(self) -> Option<AssocItemId> {
353 match self {
354 ItemInNs::Types(ModuleDefId::FunctionId(id))
355 | ItemInNs::Values(ModuleDefId::FunctionId(id)) => Some(id.into()),
356 ItemInNs::Types(ModuleDefId::ConstId(id))
357 | ItemInNs::Values(ModuleDefId::ConstId(id)) => Some(id.into()),
358 ItemInNs::Types(ModuleDefId::TypeAliasId(id))
359 | ItemInNs::Values(ModuleDefId::TypeAliasId(id)) => Some(id.into()),
360 _ => None,
361 }
362 }
363
352 /// Returns the crate defining this item (or `None` if `self` is built-in). 364 /// Returns the crate defining this item (or `None` if `self` is built-in).
353 pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> { 365 pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> {
354 Some(match self { 366 Some(match self {