Skip to content

Commit e0848ad

Browse files
committed
Turn transitive dependencies into a query
1 parent 782cda9 commit e0848ad

File tree

8 files changed

+52
-54
lines changed

8 files changed

+52
-54
lines changed

crates/base-db/src/input.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,32 @@ pub struct Crate {
460460
pub env: Env,
461461
}
462462

463+
#[salsa::tracked]
464+
impl Crate {
465+
/// Returns an iterator over all transitive dependencies of the given crate,
466+
/// including the crate itself.
467+
///
468+
/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
469+
#[salsa::tracked(returns(deref))]
470+
pub fn transitive_deps(self, db: &dyn salsa::Database) -> Box<[Crate]> {
471+
// There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
472+
// and removing that is a bit difficult.
473+
let mut worklist = vec![self];
474+
let mut deps_seen = FxHashSet::default();
475+
let mut deps = Vec::new();
476+
477+
while let Some(krate) = worklist.pop() {
478+
if !deps_seen.insert(krate) {
479+
continue;
480+
}
481+
deps.push(krate);
482+
483+
worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
484+
}
485+
deps.into_boxed_slice()
486+
}
487+
}
488+
463489
/// The mapping from [`UniqueCrateData`] to their [`Crate`] input.
464490
#[derive(Debug, Default)]
465491
pub struct CratesMap(DashMap<UniqueCrateData, Crate, BuildHasherDefault<FxHasher>>);

crates/base-db/src/lib.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
257257
#[salsa::input]
258258
fn all_crates(&self) -> Arc<Box<[Crate]>>;
259259

260-
/// Returns an iterator over all transitive dependencies of the given crate,
261-
/// including the crate itself.
262-
///
263-
/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
264-
#[salsa::transparent]
265-
fn transitive_deps(&self, crate_id: Crate) -> FxHashSet<Crate>;
266-
267260
/// Returns all transitive reverse dependencies of the given crate,
268261
/// including the crate itself.
269262
///
@@ -273,23 +266,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
273266
fn transitive_rev_deps(&self, of: Crate) -> FxHashSet<Crate>;
274267
}
275268

276-
fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Crate> {
277-
// There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
278-
// and removing that is a bit difficult.
279-
let mut worklist = vec![crate_id];
280-
let mut deps = FxHashSet::default();
281-
282-
while let Some(krate) = worklist.pop() {
283-
if !deps.insert(krate) {
284-
continue;
285-
}
286-
287-
worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
288-
}
289-
290-
deps
291-
}
292-
293269
#[salsa_macros::db]
294270
pub trait SourceDatabase: salsa::Database {
295271
/// Text of the file.

crates/hir-def/src/db.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
273273

274274
// endregion:visibilities
275275

276-
#[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
277-
fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
278276
#[salsa::invoke(crate::lang_item::crate_notable_traits)]
279-
fn crate_notable_traits(&self, krate: Crate) -> Option<Arc<[TraitId]>>;
277+
#[salsa::transparent]
278+
fn crate_notable_traits(&self, krate: Crate) -> Option<&[TraitId]>;
280279

281280
#[salsa::invoke(crate_supports_no_std)]
282281
fn crate_supports_no_std(&self, crate_id: Crate) -> bool;

crates/hir-def/src/lang_item.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use hir_expand::name::Name;
66
use intern::{Symbol, sym};
77
use rustc_hash::FxHashMap;
8-
use triomphe::Arc;
98

109
use crate::{
1110
AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, ModuleDefId,
@@ -223,16 +222,8 @@ pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option<LangIte
223222
db.attrs(item).lang_item()
224223
}
225224

226-
pub(crate) fn notable_traits_in_deps(db: &dyn DefDatabase, krate: Crate) -> Arc<[Arc<[TraitId]>]> {
227-
let _p = tracing::info_span!("notable_traits_in_deps", ?krate).entered();
228-
Arc::from_iter(
229-
db.transitive_deps(krate).into_iter().filter_map(|krate| db.crate_notable_traits(krate)),
230-
)
231-
}
232-
233-
pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Arc<[TraitId]>> {
234-
let _p = tracing::info_span!("crate_notable_traits", ?krate).entered();
235-
225+
#[salsa::tracked(returns(as_deref))]
226+
pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
236227
let mut traits = Vec::new();
237228

238229
let crate_def_map = crate_def_map(db, krate);

crates/hir-ty/src/drop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
2828
};
2929
let impls = match module.containing_block() {
3030
Some(block) => match TraitImpls::for_block(db, block) {
31-
Some(it) => it,
31+
Some(it) => &**it,
3232
None => return false,
3333
},
34-
None => &**TraitImpls::for_crate(db, module.krate()),
34+
None => TraitImpls::for_crate(db, module.krate()),
3535
};
3636
!impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).is_empty()
3737
}

crates/hir-ty/src/method_resolution.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -667,31 +667,31 @@ pub struct TraitImpls {
667667

668668
#[salsa::tracked]
669669
impl TraitImpls {
670-
#[salsa::tracked(returns(ref))]
671-
pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Arc<Self> {
670+
#[salsa::tracked(returns(deref))]
671+
pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Box<Self> {
672672
let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered();
673673

674674
let crate_def_map = crate_def_map(db, krate);
675675
let result = Self::collect_def_map(db, crate_def_map);
676-
Arc::new(result)
676+
Box::new(result)
677677
}
678678

679679
#[salsa::tracked(returns(ref))]
680+
// #[salsa::tracked(returns(as_deref))] // FIXME this does not compile
680681
pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option<Box<Self>> {
681682
let _p = tracing::info_span!("inherent_impls_in_block_query").entered();
682683

683684
let block_def_map = block_def_map(db, block);
684685
let result = Self::collect_def_map(db, block_def_map);
685686
if result.map.is_empty() { None } else { Some(Box::new(result)) }
686687
}
687-
688-
#[salsa::tracked(returns(ref))]
689-
pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc<Self>]> {
690-
db.transitive_deps(krate).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect()
691-
}
692688
}
693689

694690
impl TraitImpls {
691+
pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> impl Iterator<Item = &Self> {
692+
krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep))
693+
}
694+
695695
fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap) -> Self {
696696
let mut map = FxHashMap::default();
697697
collect(db, def_map, &mut map);
@@ -794,7 +794,7 @@ impl TraitImpls {
794794
) {
795795
let blocks = std::iter::successors(block, |block| block.loc(db).module.containing_block());
796796
blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each);
797-
Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each);
797+
Self::for_crate_and_deps(db, krate).for_each(for_each);
798798
}
799799

800800
/// Like [`Self::for_each_crate_and_block()`], but takes in account two blocks, one for a trait and one for a self type.
@@ -806,7 +806,7 @@ impl TraitImpls {
806806
for_each: &mut dyn FnMut(&TraitImpls),
807807
) {
808808
let in_self_and_deps = TraitImpls::for_crate_and_deps(db, krate);
809-
in_self_and_deps.iter().for_each(|impls| for_each(impls));
809+
in_self_and_deps.for_each(|impls| for_each(impls));
810810

811811
// We must not provide duplicate impls to the solver. Therefore we work with the following strategy:
812812
// start from each block, and walk ancestors until you meet the other block. If they never meet,

crates/hir/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ impl Crate {
250250
db.transitive_rev_deps(self.id).into_iter().map(|id| Crate { id })
251251
}
252252

253+
pub fn notable_traits_in_deps(self, db: &dyn HirDatabase) -> impl Iterator<Item = &TraitId> {
254+
self.id
255+
.transitive_deps(db)
256+
.into_iter()
257+
.filter_map(|&krate| db.crate_notable_traits(krate))
258+
.flatten()
259+
}
260+
253261
pub fn root_module(self) -> Module {
254262
Module { id: CrateRootModuleId::from(self.id).into() }
255263
}

crates/ide/src/hover.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::{iter, ops::Not};
88
use either::Either;
99
use hir::{
1010
DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics,
11-
db::DefDatabase,
1211
};
1312
use ide_db::{
1413
FileRange, FxIndexSet, MiniCore, Ranker, RootDatabase,
@@ -522,9 +521,8 @@ fn notable_traits<'db>(
522521
return Vec::new();
523522
}
524523

525-
db.notable_traits_in_deps(ty.krate(db).into())
526-
.iter()
527-
.flat_map(|it| &**it)
524+
ty.krate(db)
525+
.notable_traits_in_deps(db)
528526
.filter_map(move |&trait_| {
529527
let trait_ = trait_.into();
530528
ty.impls_trait(db, trait_, &[]).then(|| {

0 commit comments

Comments
 (0)