Skip to content

Commit cffc402

Browse files
committed
Auto merge of rust-lang#14716 - Veykril:trait-deps-query, r=Veykril
Don't merge trait_impls_in_deps results Closes rust-lang/rust-analyzer#9167 We effectively keep a lot of copies of `TraitImpl` results in memory by merging them into the result of this query. This wastes a lot of memory unnecessarily. The change here brings memory usage of self down by 50mb (at a slight cost of trait solving unfortunately, though I'm hopeful it was just noice)
2 parents 94ac1cd + 3fdff0a commit cffc402

File tree

3 files changed

+20
-29
lines changed

3 files changed

+20
-29
lines changed

crates/hir-ty/src/chalk_db.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! The implementation of `RustIrDatabase` for Chalk, which provides information
22
//! about the code that Chalk needs.
3+
use core::ops;
34
use std::{iter, sync::Arc};
45

56
use tracing::debug;
@@ -126,7 +127,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
126127
let in_deps = self.db.trait_impls_in_deps(self.krate);
127128
let in_self = self.db.trait_impls_in_crate(self.krate);
128129

129-
let impl_maps = [in_deps, in_self];
130130
let block_impls = iter::successors(self.block, |&block_id| {
131131
cov_mark::hit!(block_local_impls);
132132
self.db.block_def_map(block_id).parent().and_then(|module| module.containing_block())
@@ -146,29 +146,31 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
146146
match fps {
147147
[] => {
148148
debug!("Unrestricted search for {:?} impls...", trait_);
149-
let mut f = |impls: Arc<TraitImpls>| {
149+
let mut f = |impls: &TraitImpls| {
150150
result.extend(impls.for_trait(trait_).map(id_to_chalk));
151151
};
152-
impl_maps.into_iter().chain(block_impls).for_each(&mut f);
152+
f(&in_self);
153+
in_deps.iter().map(ops::Deref::deref).for_each(&mut f);
154+
block_impls.for_each(|it| f(&it));
153155
def_blocks
154156
.into_iter()
155157
.flatten()
156-
.map(|it| self.db.trait_impls_in_block(it))
157-
.for_each(f);
158+
.for_each(|it| f(&self.db.trait_impls_in_block(it)));
158159
}
159160
fps => {
160161
let mut f =
161-
|impls: Arc<TraitImpls>| {
162+
|impls: &TraitImpls| {
162163
result.extend(fps.iter().flat_map(|fp| {
163164
impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
164165
}));
165166
};
166-
impl_maps.into_iter().chain(block_impls).for_each(&mut f);
167+
f(&in_self);
168+
in_deps.iter().map(ops::Deref::deref).for_each(&mut f);
169+
block_impls.for_each(|it| f(&it));
167170
def_blocks
168171
.into_iter()
169172
.flatten()
170-
.map(|it| self.db.trait_impls_in_block(it))
171-
.for_each(f);
173+
.for_each(|it| f(&self.db.trait_impls_in_block(it)));
172174
}
173175
}
174176

crates/hir-ty/src/db.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
134134
fn trait_impls_in_block(&self, block: BlockId) -> Arc<TraitImpls>;
135135

136136
#[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
137-
fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<TraitImpls>;
137+
fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc<TraitImpls>]>;
138138

139139
// Interned IDs for Chalk integration
140140
#[salsa::interned]

crates/hir-ty/src/method_resolution.rs

+8-19
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,13 @@ impl TraitImpls {
160160
Arc::new(impls)
161161
}
162162

163-
pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
163+
pub(crate) fn trait_impls_in_deps_query(
164+
db: &dyn HirDatabase,
165+
krate: CrateId,
166+
) -> Arc<[Arc<Self>]> {
164167
let _p = profile::span("trait_impls_in_deps_query").detail(|| format!("{krate:?}"));
165168
let crate_graph = db.crate_graph();
166-
let mut res = Self { map: FxHashMap::default() };
167-
168-
for krate in crate_graph.transitive_deps(krate) {
169-
res.merge(&db.trait_impls_in_crate(krate));
170-
}
171-
res.shrink_to_fit();
172-
173-
Arc::new(res)
169+
crate_graph.transitive_deps(krate).map(|krate| db.trait_impls_in_crate(krate)).collect()
174170
}
175171

176172
fn shrink_to_fit(&mut self) {
@@ -209,15 +205,6 @@ impl TraitImpls {
209205
}
210206
}
211207

212-
fn merge(&mut self, other: &Self) {
213-
for (trait_, other_map) in &other.map {
214-
let map = self.map.entry(*trait_).or_default();
215-
for (fp, impls) in other_map {
216-
map.entry(*fp).or_default().extend(impls);
217-
}
218-
}
219-
}
220-
221208
/// Queries all trait impls for the given type.
222209
pub fn for_self_ty_without_blanket_impls(
223210
&self,
@@ -713,10 +700,12 @@ fn lookup_impl_assoc_item_for_trait_ref(
713700
env: Arc<TraitEnvironment>,
714701
name: &Name,
715702
) -> Option<(AssocItemId, Substitution)> {
703+
let hir_trait_id = trait_ref.hir_trait_id();
716704
let self_ty = trait_ref.self_type_parameter(Interner);
717705
let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty)?;
718706
let impls = db.trait_impls_in_deps(env.krate);
719-
let impls = impls.for_trait_and_self_ty(trait_ref.hir_trait_id(), self_ty_fp);
707+
let impls =
708+
impls.iter().flat_map(|impls| impls.for_trait_and_self_ty(hir_trait_id, self_ty_fp));
720709

721710
let table = InferenceTable::new(db, env);
722711

0 commit comments

Comments
 (0)