Skip to content

Commit d386481

Browse files
Fix some tests
1 parent 582cee2 commit d386481

File tree

4 files changed

+143
-49
lines changed

4 files changed

+143
-49
lines changed

crates/ide_completion/src/completions/flyimport.rs

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
9797
.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
9898
.into_iter()
9999
.map(|import| {
100-
let proposed_def = match import.item_to_import() {
100+
let proposed_def = match import.item_to_display() {
101101
hir::ItemInNs::Types(id) => ScopeDef::ModuleDef(id.into()),
102102
hir::ItemInNs::Values(id) => ScopeDef::ModuleDef(id.into()),
103103
hir::ItemInNs::Macros(id) => ScopeDef::MacroDef(id.into()),
@@ -809,7 +809,7 @@ fn main() {
809809
#[test]
810810
fn unresolved_assoc_item_container() {
811811
check_edit(
812-
"Item",
812+
"TEST_ASSOC",
813813
r#"
814814
mod foo {
815815
pub struct Item;
@@ -820,7 +820,7 @@ mod foo {
820820
}
821821
822822
fn main() {
823-
Item::TEST_A$0;
823+
Item::TEST_A$0
824824
}
825825
"#,
826826
r#"
@@ -844,7 +844,7 @@ fn main() {
844844
#[test]
845845
fn unresolved_assoc_item_container_with_path() {
846846
check_edit(
847-
"Item",
847+
"TEST_ASSOC",
848848
r#"
849849
mod foo {
850850
pub mod bar {
@@ -857,7 +857,7 @@ mod foo {
857857
}
858858
859859
fn main() {
860-
bar::Item::TEST_A$0;
860+
bar::Item::TEST_A$0
861861
}
862862
"#,
863863
r#"
@@ -876,6 +876,61 @@ mod foo {
876876
fn main() {
877877
bar::Item::TEST_ASSOC
878878
}
879+
"#,
880+
);
881+
}
882+
883+
#[test]
884+
fn unresolved_assoc_item_container_and_trait_with_path() {
885+
check_edit(
886+
"TEST_ASSOC",
887+
r#"
888+
mod foo {
889+
pub mod bar {
890+
pub trait SomeTrait {
891+
const TEST_ASSOC: usize;
892+
}
893+
}
894+
895+
pub mod baz {
896+
use super::bar::SomeTrait;
897+
898+
pub struct Item;
899+
900+
impl SomeTrait for Item {
901+
const TEST_ASSOC: usize = 3;
902+
}
903+
}
904+
}
905+
906+
fn main() {
907+
baz::Item::TEST_A$0
908+
}
909+
"#,
910+
r#"
911+
use foo::{bar::SomeTrait, baz};
912+
913+
mod foo {
914+
pub mod bar {
915+
pub trait SomeTrait {
916+
const TEST_ASSOC: usize;
917+
}
918+
}
919+
920+
pub mod baz {
921+
use super::bar::SomeTrait;
922+
923+
pub struct Item;
924+
925+
impl SomeTrait for Item {
926+
const TEST_ASSOC: usize = 3;
927+
}
928+
}
929+
}
930+
931+
fn main() {
932+
baz::Item::TEST_ASSOC
933+
}
879934
"#,
880935
);
881936
}

crates/ide_completion/src/render.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ mod builder_ext;
1313
use hir::{
1414
AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type,
1515
};
16-
use ide_db::{helpers::SnippetCap, RootDatabase, SymbolKind};
16+
use ide_db::{
17+
helpers::{item_name, SnippetCap},
18+
RootDatabase, SymbolKind,
19+
};
1720
use syntax::TextRange;
1821

1922
use crate::{
@@ -56,7 +59,7 @@ pub(crate) fn render_resolution_with_import<'a>(
5659
ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(),
5760
ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(),
5861
ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(),
59-
_ => import_edit.import.display_path().segments().last()?.to_string(),
62+
_ => item_name(ctx.db(), import_edit.import.item_to_display())?.to_string(),
6063
};
6164
Render::new(ctx).render_resolution(local_name, Some(import_edit), resolution).map(|mut item| {
6265
item.completion_kind = CompletionKind::Magic;

crates/ide_db/src/helpers.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@
22
pub mod insert_use;
33
pub mod import_assets;
44

5-
use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait};
5+
use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait};
66
use syntax::ast::{self, make};
77

88
use crate::RootDatabase;
99

10+
pub fn item_name(db: &RootDatabase, item: ItemInNs) -> Option<Name> {
11+
match item {
12+
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).name(db),
13+
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).name(db),
14+
ItemInNs::Macros(macro_def_id) => MacroDef::from(macro_def_id).name(db),
15+
}
16+
}
17+
1018
/// Converts the mod path struct into its ast representation.
1119
pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
1220
let _p = profile::span("mod_path_to_ast");

crates/ide_db/src/helpers/import_assets.rs

Lines changed: 69 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Look up accessible paths for items.
22
use either::Either;
33
use hir::{
4-
AsAssocItem, AssocItem, Crate, ItemInNs, MacroDef, ModPath, Module, ModuleDef, Name,
5-
PrefixKind, Semantics,
4+
AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module,
5+
ModuleDef, PathResolution, PrefixKind, Semantics, Type,
66
};
77
use rustc_hash::FxHashSet;
88
use syntax::{ast, AstNode};
@@ -12,6 +12,8 @@ use crate::{
1212
RootDatabase,
1313
};
1414

15+
use super::item_name;
16+
1517
#[derive(Debug)]
1618
pub enum ImportCandidate {
1719
// A path, qualified (`std::collections::HashMap`) or not (`HashMap`).
@@ -28,7 +30,7 @@ pub enum ImportCandidate {
2830

2931
#[derive(Debug)]
3032
pub struct TraitImportCandidate {
31-
pub receiver_ty: hir::Type,
33+
pub receiver_ty: Type,
3234
pub name: NameToImport,
3335
}
3436

@@ -62,7 +64,7 @@ impl NameToImport {
6264
#[derive(Debug)]
6365
pub struct ImportAssets {
6466
import_candidate: ImportCandidate,
65-
module_with_candidate: hir::Module,
67+
module_with_candidate: Module,
6668
}
6769

6870
impl ImportAssets {
@@ -104,7 +106,7 @@ impl ImportAssets {
104106

105107
pub fn for_fuzzy_method_call(
106108
module_with_method_call: Module,
107-
receiver_ty: hir::Type,
109+
receiver_ty: Type,
108110
fuzzy_method_name: String,
109111
) -> Option<Self> {
110112
Some(Self {
@@ -184,7 +186,7 @@ impl ImportAssets {
184186
fn search_for(
185187
&self,
186188
sema: &Semantics<RootDatabase>,
187-
prefixed: Option<hir::PrefixKind>,
189+
prefixed: Option<PrefixKind>,
188190
) -> Vec<LocatedImport> {
189191
let current_crate = self.module_with_candidate.krate();
190192

@@ -223,7 +225,7 @@ impl ImportAssets {
223225
fn applicable_defs(
224226
&self,
225227
db: &RootDatabase,
226-
prefixed: Option<hir::PrefixKind>,
228+
prefixed: Option<PrefixKind>,
227229
unfiltered_defs: impl Iterator<Item = Either<ModuleDef, MacroDef>>,
228230
) -> FxHashSet<LocatedImport> {
229231
let current_crate = self.module_with_candidate.krate();
@@ -266,10 +268,10 @@ fn path_applicable_imports(
266268
let (assoc_original, candidate) = match def {
267269
Either::Left(module_def) => match module_def.as_assoc_item(db) {
268270
Some(assoc_item) => match assoc_item.container(db) {
269-
hir::AssocItemContainer::Trait(trait_) => {
271+
AssocItemContainer::Trait(trait_) => {
270272
(Some(module_def), ItemInNs::from(ModuleDef::from(trait_)))
271273
}
272-
hir::AssocItemContainer::Impl(impl_) => (
274+
AssocItemContainer::Impl(impl_) => (
273275
Some(module_def),
274276
ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?)),
275277
),
@@ -296,6 +298,7 @@ fn path_applicable_imports(
296298
};
297299

298300
// TODO kb need to remove turbofish from the qualifier, maybe use the segments instead?
301+
// TODO kb sorting is changed now, return back?
299302
let unresolved_qualifier_string = unresolved_qualifier.to_string();
300303
let unresolved_first_segment_string = unresolved_first_segment.to_string();
301304

@@ -305,38 +308,35 @@ fn path_applicable_imports(
305308
candidate_path_string.contains(&unresolved_qualifier_string)
306309
&& candidate_path_string.contains(&unresolved_first_segment_string)
307310
})
308-
// TODO kb need to adjust the return type: I get the results rendered rather badly
309311
.filter_map(|(candidate_path, (assoc_original, candidate))| {
310-
if let Some(assoc_original) = assoc_original {
311-
if item_name(db, candidate)?.to_string() == unresolved_first_segment_string {
312-
return Some(LocatedImport::new(
313-
candidate_path.clone(),
314-
ItemInNs::from(assoc_original),
315-
Some((candidate_path, candidate)),
316-
));
317-
}
318-
}
312+
let found_segment_resolution = item_name(db, candidate)
313+
.map(|name| name.to_string() == unresolved_first_segment_string)
314+
.unwrap_or(false);
315+
let (import_path, item_to_import) = if found_segment_resolution {
316+
(candidate_path.clone(), candidate)
317+
} else {
318+
let matching_module =
319+
module_with_matching_name(db, &unresolved_first_segment_string, candidate)?;
320+
let module_item = ItemInNs::from(ModuleDef::from(matching_module));
321+
(import_path_locator(module_item)?, module_item)
322+
};
319323

320-
let matching_module =
321-
module_with_matching_name(db, &unresolved_first_segment_string, candidate)?;
322-
let item = ItemInNs::from(ModuleDef::from(matching_module));
323-
Some(LocatedImport::new(
324-
import_path_locator(item)?,
325-
item,
326-
Some((candidate_path, candidate)),
327-
))
324+
Some(match assoc_original {
325+
Some(assoc_original) => LocatedImport::new(
326+
import_path.clone(),
327+
item_to_import,
328+
Some((import_path, ItemInNs::from(assoc_original))),
329+
),
330+
None => LocatedImport::new(
331+
import_path,
332+
item_to_import,
333+
if found_segment_resolution { None } else { Some((candidate_path, candidate)) },
334+
),
335+
})
328336
})
329337
.collect()
330338
}
331339

332-
fn item_name(db: &RootDatabase, item: ItemInNs) -> Option<Name> {
333-
match item {
334-
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).name(db),
335-
ItemInNs::Values(module_def_id) => ModuleDef::from(module_def_id).name(db),
336-
ItemInNs::Macros(macro_def_id) => MacroDef::from(macro_def_id).name(db),
337-
}
338-
}
339-
340340
fn item_module(db: &RootDatabase, item: ItemInNs) -> Option<Module> {
341341
match item {
342342
ItemInNs::Types(module_def_id) => ModuleDef::from(module_def_id).module(db),
@@ -404,10 +404,20 @@ fn trait_applicable_items(
404404
}
405405

406406
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
407+
let item_path = import_path_locator(item)?;
408+
409+
let assoc_item = assoc_to_item(assoc);
410+
let assoc_item_path = match assoc.container(db) {
411+
AssocItemContainer::Trait(_) => item_path.clone(),
412+
AssocItemContainer::Impl(impl_) => import_path_locator(ItemInNs::from(
413+
ModuleDef::from(impl_.target_ty(db).as_adt()?),
414+
))?,
415+
};
416+
407417
located_imports.insert(LocatedImport::new(
408-
import_path_locator(item)?,
418+
item_path,
409419
item,
410-
None,
420+
Some((assoc_item_path, assoc_item)),
411421
));
412422
}
413423
None::<()>
@@ -423,10 +433,20 @@ fn trait_applicable_items(
423433
let assoc = function.as_assoc_item(db)?;
424434
if required_assoc_items.contains(&assoc) {
425435
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
436+
let item_path = import_path_locator(item)?;
437+
438+
let assoc_item = assoc_to_item(assoc);
439+
let assoc_item_path = match assoc.container(db) {
440+
AssocItemContainer::Trait(_) => item_path.clone(),
441+
AssocItemContainer::Impl(impl_) => import_path_locator(ItemInNs::from(
442+
ModuleDef::from(impl_.target_ty(db).as_adt()?),
443+
))?,
444+
};
445+
426446
located_imports.insert(LocatedImport::new(
427-
import_path_locator(item)?,
447+
item_path,
428448
item,
429-
None,
449+
Some((assoc_item_path, assoc_item)),
430450
));
431451
}
432452
None::<()>
@@ -437,11 +457,19 @@ fn trait_applicable_items(
437457
located_imports
438458
}
439459

460+
fn assoc_to_item(assoc: AssocItem) -> ItemInNs {
461+
match assoc {
462+
AssocItem::Function(f) => ItemInNs::from(ModuleDef::from(f)),
463+
AssocItem::Const(c) => ItemInNs::from(ModuleDef::from(c)),
464+
AssocItem::TypeAlias(t) => ItemInNs::from(ModuleDef::from(t)),
465+
}
466+
}
467+
440468
fn get_mod_path(
441469
db: &RootDatabase,
442470
item_to_search: ItemInNs,
443471
module_with_candidate: &Module,
444-
prefixed: Option<hir::PrefixKind>,
472+
prefixed: Option<PrefixKind>,
445473
) -> Option<ModPath> {
446474
if let Some(prefix_kind) = prefixed {
447475
module_with_candidate.find_use_path_prefixed(db, item_to_search, prefix_kind)
@@ -509,7 +537,7 @@ fn path_import_candidate(
509537
return None;
510538
}
511539
}
512-
Some(hir::PathResolution::Def(hir::ModuleDef::Adt(assoc_item_path))) => {
540+
Some(PathResolution::Def(ModuleDef::Adt(assoc_item_path))) => {
513541
ImportCandidate::TraitAssocItem(TraitImportCandidate {
514542
receiver_ty: assoc_item_path.ty(sema.db),
515543
name,

0 commit comments

Comments
 (0)