From a2783df3f00eb2cc8d6832f44fe8aa7ea3be46c8 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 11 Apr 2020 13:11:33 +0200 Subject: Look up impls by self type This speeds up inference in analysis-stats by ~30% (even more with the recursive solver). --- crates/ra_hir_ty/src/method_resolution.rs | 45 +++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_ty/src/method_resolution.rs') diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 74a0bc7db..657284fd0 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -34,7 +34,7 @@ impl TyFingerprint { /// Creates a TyFingerprint for looking up an impl. Only certain types can /// have impls: if we have some `struct S`, we can have an `impl S`, but not /// `impl &S`. Hence, this will return `None` for reference types and such. - fn for_impl(ty: &Ty) -> Option { + pub(crate) fn for_impl(ty: &Ty) -> Option { match ty { Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), _ => None, @@ -45,7 +45,7 @@ impl TyFingerprint { #[derive(Debug, PartialEq, Eq)] pub struct CrateImplDefs { impls: FxHashMap>, - impls_by_trait: FxHashMap>, + impls_by_trait: FxHashMap, Vec>>, } impl CrateImplDefs { @@ -59,7 +59,14 @@ impl CrateImplDefs { for impl_id in module_data.scope.impls() { match db.impl_trait(impl_id) { Some(tr) => { - res.impls_by_trait.entry(tr.value.trait_).or_default().push(impl_id); + let self_ty = db.impl_self_ty(impl_id); + let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); + res.impls_by_trait + .entry(tr.value.trait_) + .or_default() + .entry(self_ty_fp) + .or_default() + .push(impl_id); } None => { let self_ty = db.impl_self_ty(impl_id); @@ -79,11 +86,39 @@ impl CrateImplDefs { } pub fn lookup_impl_defs_for_trait(&self, tr: TraitId) -> impl Iterator + '_ { - self.impls_by_trait.get(&tr).into_iter().flatten().copied() + self.impls_by_trait + .get(&tr) + .into_iter() + .flat_map(|m| m.values().flat_map(|v| v.iter().copied())) + } + + pub fn lookup_impl_defs_for_trait_and_ty( + &self, + tr: TraitId, + fp: TyFingerprint, + ) -> impl Iterator + '_ { + self.impls_by_trait + .get(&tr) + .and_then(|m| m.get(&Some(fp))) + .into_iter() + .flatten() + .copied() + .chain( + self.impls_by_trait + .get(&tr) + .and_then(|m| m.get(&None)) + .into_iter() + .flatten() + .copied(), + ) } pub fn all_impls<'a>(&'a self) -> impl Iterator + 'a { - self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() + self.impls + .values() + .chain(self.impls_by_trait.values().flat_map(|m| m.values())) + .flatten() + .copied() } } -- cgit v1.2.3