This commit is contained in:
Kirill Bulatov 2021-02-21 23:52:29 +02:00
parent 7584260b9a
commit f08c0cdd2a

View file

@ -183,39 +183,41 @@ impl ImportAssets {
}
fn applicable_defs<'a>(
&self,
&'a self,
sema: &'a Semantics<RootDatabase>,
prefixed: Option<hir::PrefixKind>,
unfiltered_imports: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>,
unfiltered_defs: impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a,
) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> {
let current_crate = self.module_with_candidate.krate();
let db = sema.db;
match &self.import_candidate {
ImportCandidate::Path(path_candidate) => path_applicable_defs(
ImportCandidate::Path(path_candidate) => Box::new(path_applicable_defs(
sema,
path_candidate,
unfiltered_imports,
self.module_with_candidate,
prefixed,
unfiltered_defs
.into_iter()
.map(|def| def.either(ItemInNs::from, ItemInNs::from))
.filter_map(move |item_to_search| {
get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed)
.zip(Some(item_to_search))
}),
)),
ImportCandidate::TraitAssocItem(trait_candidate) => Box::new(
trait_applicable_defs(db, current_crate, trait_candidate, true, unfiltered_defs)
.into_iter()
.filter_map(move |item_to_search| {
get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed)
.zip(Some(item_to_search))
}),
),
ImportCandidate::TraitAssocItem(trait_candidate) => trait_applicable_defs(
db,
current_crate,
trait_candidate,
true,
unfiltered_imports,
self.module_with_candidate,
prefixed,
),
ImportCandidate::TraitMethod(trait_candidate) => trait_applicable_defs(
db,
current_crate,
trait_candidate,
false,
unfiltered_imports,
self.module_with_candidate,
prefixed,
ImportCandidate::TraitMethod(trait_candidate) => Box::new(
trait_applicable_defs(db, current_crate, trait_candidate, false, unfiltered_defs)
.into_iter()
.filter_map(move |item_to_search| {
get_mod_path(db, item_to_search, &self.module_with_candidate, prefixed)
.zip(Some(item_to_search))
}),
),
}
}
@ -224,22 +226,12 @@ impl ImportAssets {
fn path_applicable_defs<'a>(
sema: &'a Semantics<RootDatabase>,
path_candidate: &PathImportCandidate,
unfiltered_defs: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>,
module_with_candidate: Module,
prefixed: Option<hir::PrefixKind>,
) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> {
let applicable_defs = unfiltered_defs
.map(|candidate| candidate.either(ItemInNs::from, ItemInNs::from))
.filter_map(move |item_to_search| {
get_mod_path(sema.db, item_to_search, &module_with_candidate, prefixed)
.zip(Some(item_to_search))
});
unfiltered_defs: impl Iterator<Item = (ModPath, ItemInNs)> + 'a,
) -> impl Iterator<Item = (ModPath, ItemInNs)> + 'a {
let unresolved_qualifier = match &path_candidate.unresolved_qualifier {
Some(qualifier) => qualifier,
None => {
// TODO kb too many boxes tossed around
return Box::new(applicable_defs);
return unfiltered_defs;
}
};
@ -252,7 +244,7 @@ fn path_applicable_defs<'a>(
// first segment is already unresolved, need to turn it into ModuleDef somehow
}
return Box::new(applicable_defs);
return unfiltered_defs;
}
fn resolve_qualifier_start(
@ -269,10 +261,8 @@ fn trait_applicable_defs<'a>(
current_crate: Crate,
trait_candidate: &TraitImportCandidate,
trait_assoc_item: bool,
unfiltered_defs: Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a>,
module_with_candidate: Module,
prefixed: Option<hir::PrefixKind>,
) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> {
unfiltered_defs: impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a,
) -> FxHashSet<ItemInNs> {
let mut required_assoc_items = FxHashSet::default();
let trait_candidates = unfiltered_defs
@ -287,7 +277,7 @@ fn trait_applicable_defs<'a>(
})
.collect();
let mut applicable_defs = FxHashSet::default();
let mut applicable_traits = FxHashSet::default();
if trait_assoc_item {
trait_candidate.receiver_ty.iterate_path_candidates(
@ -302,7 +292,8 @@ fn trait_applicable_defs<'a>(
return None;
}
}
applicable_defs.insert(assoc_to_module_def(assoc));
applicable_traits
.insert(ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)));
}
None::<()>
},
@ -316,25 +307,15 @@ fn trait_applicable_defs<'a>(
|_, function| {
let assoc = function.as_assoc_item(db)?;
if required_assoc_items.contains(&assoc) {
applicable_defs.insert(assoc_to_module_def(assoc));
applicable_traits
.insert(ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?)));
}
None::<()>
},
)
};
Box::new(
applicable_defs
.into_iter()
.filter_map(move |candidate| {
let canidate_trait = candidate.as_assoc_item(db)?.containing_trait(db)?;
Some(ItemInNs::from(ModuleDef::from(canidate_trait)))
})
.filter_map(move |item_to_search| {
get_mod_path(db, item_to_search, &module_with_candidate, prefixed)
.zip(Some(item_to_search))
}),
)
applicable_traits
}
fn get_mod_path(
@ -350,14 +331,6 @@ fn get_mod_path(
}
}
fn assoc_to_module_def(assoc: AssocItem) -> ModuleDef {
match assoc {
AssocItem::Function(f) => f.into(),
AssocItem::Const(c) => c.into(),
AssocItem::TypeAlias(t) => t.into(),
}
}
impl ImportCandidate {
fn for_method_call(
sema: &Semantics<RootDatabase>,