diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs index 07ee7bdfd7e..369bc3350b7 100644 --- a/crates/hir_def/src/import_map.rs +++ b/crates/hir_def/src/import_map.rs @@ -1094,27 +1094,4 @@ mod tests { expect![[r#""#]], ); } - - #[test] - fn search_with_path() { - check_search( - r#" -//- /main.rs crate:main deps:dep -//- /dep.rs crate:dep -pub mod foo { - pub mod bar { - pub mod baz { - pub trait Display { - fn fmt(); - } - } - } -}"#, - "main", - Query::new("baz::fmt".to_string()).search_mode(SearchMode::Fuzzy), - expect![[r#" - dep::foo::bar::baz::Display::fmt (a) - "#]], - ); - } } diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index efb91fe0e0e..8a11cba4110 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs @@ -21,8 +21,9 @@ //! ``` //! //! Also completes associated items, that require trait imports. -//! If any unresolved and/or partially-qualified path predeces the input, it will be taken into account: only the items with import string -//! containing this whole path will be considered and the corresponding path import will be added: +//! If any unresolved and/or partially-qualified path predeces the input, it will be taken into account. +//! Currently, only the imports with their import path ending with the whole qialifier will be proposed +//! (no fuzzy matching for qualifier). //! //! ``` //! mod foo { @@ -187,7 +188,6 @@ fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option<I ctx.scope.clone(), )?; - // TODO kb bad: with the path prefix, the "min 3 symbols" limit applies. Fix in a separate PR on the symbol_index level if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_)) && fuzzy_name_length < 2 { @@ -937,7 +937,6 @@ mod foo { } fn main() { - let zz = "sdsd"; bar::Ass$0 }"#, expect![[]], diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index b78d1969d2e..9bdc938774b 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs @@ -314,19 +314,21 @@ fn import_for_item( let import_path_candidate = mod_path(original_item_candidate)?; let import_path_string = import_path_candidate.to_string(); + let expected_import_end = if item_as_assoc(db, original_item).is_some() { + unresolved_qualifier.to_string() + } else { + format!("{}::{}", unresolved_qualifier, item_name(db, original_item)?) + }; if !import_path_string.contains(unresolved_first_segment) - || !import_path_string.contains(unresolved_qualifier) + || !import_path_string.ends_with(&expected_import_end) { return None; } let segment_import = find_import_for_segment(db, original_item_candidate, &unresolved_first_segment)?; - let trait_item_to_import = original_item - .as_module_def_id() - .and_then(|module_def_id| { - ModuleDef::from(module_def_id).as_assoc_item(db)?.containing_trait(db) - }) + let trait_item_to_import = item_as_assoc(db, original_item) + .and_then(|assoc| assoc.containing_trait(db)) .map(|trait_| ItemInNs::from(ModuleDef::from(trait_))); Some(match (segment_import == original_item_candidate, trait_item_to_import) { (true, Some(_)) => { @@ -358,19 +360,15 @@ fn import_for_item( fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> { Some(match item { - ItemInNs::Types(module_def_id) | ItemInNs::Values(module_def_id) => { - let module_def = ModuleDef::from(module_def_id); - - match module_def.as_assoc_item(db) { - Some(assoc_item) => match assoc_item.container(db) { - AssocItemContainer::Trait(trait_) => ItemInNs::from(ModuleDef::from(trait_)), - AssocItemContainer::Impl(impl_) => { - ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?)) - } - }, - None => item, - } - } + ItemInNs::Types(_) | ItemInNs::Values(_) => match item_as_assoc(db, item) { + Some(assoc_item) => match assoc_item.container(db) { + AssocItemContainer::Trait(trait_) => ItemInNs::from(ModuleDef::from(trait_)), + AssocItemContainer::Impl(impl_) => { + ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?)) + } + }, + None => item, + }, ItemInNs::Macros(_) => item, }) } @@ -427,7 +425,7 @@ fn trait_applicable_items( let trait_candidates = items_with_candidate_name .into_iter() - .filter_map(|input| ModuleDef::from(input.as_module_def_id()?).as_assoc_item(db)) + .filter_map(|input| item_as_assoc(db, input)) .filter_map(|assoc| { let assoc_item_trait = assoc.containing_trait(db)?; required_assoc_items.insert(assoc); @@ -583,3 +581,8 @@ fn path_import_candidate( None => ImportCandidate::Path(PathImportCandidate { qualifier: Qualifier::Absent, name }), }) } + +fn item_as_assoc(db: &RootDatabase, item: ItemInNs) -> Option<AssocItem> { + item.as_module_def_id() + .and_then(|module_def_id| ModuleDef::from(module_def_id).as_assoc_item(db)) +}