Look up impls by self type

This speeds up inference in analysis-stats by ~30% (even more with the recursive
solver).
This commit is contained in:
Florian Diebold
2020-04-11 13:11:33 +02:00
parent 8bd14a3483
commit a2783df3f0
4 changed files with 65 additions and 14 deletions

View File

@@ -7,7 +7,7 @@ use ra_db::{impl_intern_key, salsa, CrateId};
use ra_prof::profile;
use rustc_hash::FxHashSet;
use crate::{db::HirDatabase, DebruijnIndex};
use crate::{db::HirDatabase, method_resolution::TyFingerprint, DebruijnIndex};
use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
@@ -40,7 +40,12 @@ pub(crate) fn impls_for_trait_query(
db: &dyn HirDatabase,
krate: CrateId,
trait_: TraitId,
self_ty_fp: Option<TyFingerprint>,
) -> Arc<[ImplId]> {
// FIXME: We could be a lot smarter here - because of the orphan rules and
// the fact that the trait and the self type need to be in the dependency
// tree of a crate somewhere for an impl to exist, we could skip looking in
// a lot of crates completely
let mut impls = FxHashSet::default();
// We call the query recursively here. On the one hand, this means we can
// reuse results from queries for different crates; on the other hand, this
@@ -48,10 +53,13 @@ pub(crate) fn impls_for_trait_query(
// ones the user is editing), so this may actually be a waste of memory. I'm
// doing it like this mainly for simplicity for now.
for dep in &db.crate_graph()[krate].dependencies {
impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter());
impls.extend(db.impls_for_trait(dep.crate_id, trait_, self_ty_fp).iter());
}
let crate_impl_defs = db.impls_in_crate(krate);
impls.extend(crate_impl_defs.lookup_impl_defs_for_trait(trait_));
match self_ty_fp {
Some(fp) => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait_and_ty(trait_, fp)),
None => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait(trait_)),
}
impls.into_iter().collect()
}