aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-20 23:14:21 +0100
committerGitHub <[email protected]>2020-06-20 23:14:21 +0100
commit04d64267de2c9ade61ae9fdbc98114599c11a2d7 (patch)
treeeb18414e177eb0e40e902c5ec45cebc49ac8d43b /crates/ra_hir_ty/src/traits.rs
parent92fef01f6506b33c0489e020df1ad9fdce2fac9b (diff)
parenta3c2f5126fb9f2575584d12335b6e7e82deec45a (diff)
Merge #4947
4947: Replace `impls_in_trait` query with smarter use of `CrateImplDefs` r=matklad a=jonas-schievink `impls_in_trait` was allocating a whopping ~400 MB of RAM when running analysis-stats on r-a itself. Remove it, instead adding a query that computes a summary `CrateImplDefs` map for all transitive dependencies. This can probably still be made more efficient, but this already reduces the peak memory usage by 25% without much performance impact on analysis-stats. **Before**: ``` Total: 34.962107188s, 2083mb allocated 2141mb resident 422mb ImplsForTraitQuery (deps) 250mb CrateDefMapQueryQuery 147mb MacroArgQuery 140mb TraitSolveQuery (deps) 68mb InferQueryQuery (deps) 62mb ImplDatumQuery (deps) ``` **After**: ``` Total: 35.261100358s, 1520mb allocated 1569mb resident 250mb CrateDefMapQueryQuery 147mb MacroArgQuery 144mb TraitSolveQuery (deps) 68mb InferQueryQuery (deps) 61mb ImplDatumQuery (deps) 45mb BodyQuery 45mb ImplDatumQuery ``` Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/traits.rs')
-rw-r--r--crates/ra_hir_ty/src/traits.rs31
1 files changed, 1 insertions, 30 deletions
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 892fbd6d1..6f43c3a22 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -7,9 +7,8 @@ use hir_def::{
7}; 7};
8use ra_db::{impl_intern_key, salsa, CrateId}; 8use ra_db::{impl_intern_key, salsa, CrateId};
9use ra_prof::profile; 9use ra_prof::profile;
10use rustc_hash::FxHashSet;
11 10
12use crate::{db::HirDatabase, method_resolution::TyFingerprint, DebruijnIndex}; 11use crate::{db::HirDatabase, DebruijnIndex};
13 12
14use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
15 14
@@ -38,34 +37,6 @@ fn create_chalk_solver() -> chalk_solve::Solver<Interner> {
38 solver_choice.into_solver() 37 solver_choice.into_solver()
39} 38}
40 39
41/// Collects impls for the given trait in the whole dependency tree of `krate`.
42pub(crate) fn impls_for_trait_query(
43 db: &dyn HirDatabase,
44 krate: CrateId,
45 trait_: TraitId,
46 self_ty_fp: Option<TyFingerprint>,
47) -> Arc<[ImplId]> {
48 // FIXME: We could be a lot smarter here - because of the orphan rules and
49 // the fact that the trait and the self type need to be in the dependency
50 // tree of a crate somewhere for an impl to exist, we could skip looking in
51 // a lot of crates completely
52 let mut impls = FxHashSet::default();
53 // We call the query recursively here. On the one hand, this means we can
54 // reuse results from queries for different crates; on the other hand, this
55 // will only ever get called for a few crates near the root of the tree (the
56 // ones the user is editing), so this may actually be a waste of memory. I'm
57 // doing it like this mainly for simplicity for now.
58 for dep in &db.crate_graph()[krate].dependencies {
59 impls.extend(db.impls_for_trait(dep.crate_id, trait_, self_ty_fp).iter());
60 }
61 let crate_impl_defs = db.impls_in_crate(krate);
62 match self_ty_fp {
63 Some(fp) => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait_and_ty(trait_, fp)),
64 None => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait(trait_)),
65 }
66 impls.into_iter().collect()
67}
68
69/// A set of clauses that we assume to be true. E.g. if we are inside this function: 40/// A set of clauses that we assume to be true. E.g. if we are inside this function:
70/// ```rust 41/// ```rust
71/// fn foo<T: Default>(t: T) {} 42/// fn foo<T: Default>(t: T) {}