mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
completions: speed up completions by filtering non-applicable traits
This commit is contained in:
parent
9f0495761a
commit
c246a93046
6 changed files with 243 additions and 4 deletions
|
@ -1,8 +1,9 @@
|
|||
//! Look up accessible paths for items.
|
||||
|
||||
use hir::{
|
||||
AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, ModPath, Module, ModuleDef, Name,
|
||||
PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type,
|
||||
db::HirDatabase, AsAssocItem, AssocItem, AssocItemContainer, Crate, HasCrate, ItemInNs,
|
||||
ModPath, Module, ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics,
|
||||
SemanticsScope, Trait, Type,
|
||||
};
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
@ -517,7 +518,7 @@ fn trait_applicable_items(
|
|||
let related_traits = inherent_traits.chain(env_traits).collect::<FxHashSet<_>>();
|
||||
|
||||
let mut required_assoc_items = FxHashSet::default();
|
||||
let trait_candidates: FxHashSet<_> = items_locator::items_with_name(
|
||||
let mut trait_candidates: FxHashSet<_> = items_locator::items_with_name(
|
||||
sema,
|
||||
current_crate,
|
||||
trait_candidate.assoc_item_name.clone(),
|
||||
|
@ -538,6 +539,32 @@ fn trait_applicable_items(
|
|||
})
|
||||
.collect();
|
||||
|
||||
trait_candidates.retain(|&candidate_trait_id| {
|
||||
// we care about the following cases:
|
||||
// 1. Trait's definition crate
|
||||
// 2. Definition crates for all trait's generic arguments
|
||||
// a. This is recursive for fundamental types: `Into<Box<A>> for ()`` is OK, but
|
||||
// `Into<Vec<A>> for ()`` is *not*.
|
||||
// 3. Receiver type definition crate
|
||||
// a. This is recursive for fundamental types
|
||||
let defining_crate_for_trait = Trait::from(candidate_trait_id).krate(db);
|
||||
let Some(receiver) = trait_candidate.receiver_ty.fingerprint_for_trait_impl() else {
|
||||
return false;
|
||||
};
|
||||
let definitions_exist_in_trait_crate = db
|
||||
.trait_impls_in_crate(defining_crate_for_trait.into())
|
||||
.has_impls_for_trait_and_self_ty(candidate_trait_id, receiver);
|
||||
|
||||
// this is a closure for laziness: if `definitions_exist_in_trait_crate` is true,
|
||||
// we can avoid a second db lookup.
|
||||
let definitions_exist_in_receiver_crate = || {
|
||||
db.trait_impls_in_crate(trait_candidate.receiver_ty.krate(db).into())
|
||||
.has_impls_for_trait_and_self_ty(candidate_trait_id, receiver)
|
||||
};
|
||||
|
||||
definitions_exist_in_trait_crate || definitions_exist_in_receiver_crate()
|
||||
});
|
||||
|
||||
let mut located_imports = FxHashSet::default();
|
||||
let mut trait_import_paths = FxHashMap::default();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue