Unnamed repository; edit this file 'description' to name the repository.
Turn transitive dependencies into a query
Lukas Wirth 5 months ago
parent 782cda9 · commit 66b6a1e
-rw-r--r--crates/base-db/src/input.rs26
-rw-r--r--crates/base-db/src/lib.rs24
-rw-r--r--crates/hir-def/src/db.rs5
-rw-r--r--crates/hir-def/src/lang_item.rs13
-rw-r--r--crates/hir-ty/src/drop.rs4
-rw-r--r--crates/hir-ty/src/method_resolution.rs2
-rw-r--r--crates/hir-ty/src/tests/incremental.rs1
-rw-r--r--crates/hir/src/lib.rs8
-rw-r--r--crates/ide/src/hover.rs6
9 files changed, 44 insertions, 45 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index ffd82d5043..f9e69a0326 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -460,6 +460,32 @@ pub struct Crate {
pub env: Env,
}
+#[salsa::tracked]
+impl Crate {
+ /// Returns an iterator over all transitive dependencies of the given crate,
+ /// including the crate itself.
+ ///
+ /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
+ #[salsa::tracked(returns(deref))]
+ pub fn transitive_deps(self, db: &dyn salsa::Database) -> Box<[Crate]> {
+ // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
+ // and removing that is a bit difficult.
+ let mut worklist = vec![self];
+ let mut deps_seen = FxHashSet::default();
+ let mut deps = Vec::new();
+
+ while let Some(krate) = worklist.pop() {
+ if !deps_seen.insert(krate) {
+ continue;
+ }
+ deps.push(krate);
+
+ worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
+ }
+ deps.into_boxed_slice()
+ }
+}
+
/// The mapping from [`UniqueCrateData`] to their [`Crate`] input.
#[derive(Debug, Default)]
pub struct CratesMap(DashMap<UniqueCrateData, Crate, BuildHasherDefault<FxHasher>>);
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 90e0aa9065..4d226f5cbf 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -257,13 +257,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
#[salsa::input]
fn all_crates(&self) -> Arc<Box<[Crate]>>;
- /// Returns an iterator over all transitive dependencies of the given crate,
- /// including the crate itself.
- ///
- /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
- #[salsa::transparent]
- fn transitive_deps(&self, crate_id: Crate) -> FxHashSet<Crate>;
-
/// Returns all transitive reverse dependencies of the given crate,
/// including the crate itself.
///
@@ -273,23 +266,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
fn transitive_rev_deps(&self, of: Crate) -> FxHashSet<Crate>;
}
-fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Crate> {
- // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible
- // and removing that is a bit difficult.
- let mut worklist = vec![crate_id];
- let mut deps = FxHashSet::default();
-
- while let Some(krate) = worklist.pop() {
- if !deps.insert(krate) {
- continue;
- }
-
- worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id));
- }
-
- deps
-}
-
#[salsa_macros::db]
pub trait SourceDatabase: salsa::Database {
/// Text of the file.
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 4e1d598623..925a078e82 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -273,10 +273,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
// endregion:visibilities
- #[salsa::invoke(crate::lang_item::notable_traits_in_deps)]
- fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>;
#[salsa::invoke(crate::lang_item::crate_notable_traits)]
- fn crate_notable_traits(&self, krate: Crate) -> Option<Arc<[TraitId]>>;
+ #[salsa::transparent]
+ fn crate_notable_traits(&self, krate: Crate) -> Option<&[TraitId]>;
#[salsa::invoke(crate_supports_no_std)]
fn crate_supports_no_std(&self, crate_id: Crate) -> bool;
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index df0705bf90..91a90f6d84 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -5,7 +5,6 @@
use hir_expand::name::Name;
use intern::{Symbol, sym};
use rustc_hash::FxHashMap;
-use triomphe::Arc;
use crate::{
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
db.attrs(item).lang_item()
}
-pub(crate) fn notable_traits_in_deps(db: &dyn DefDatabase, krate: Crate) -> Arc<[Arc<[TraitId]>]> {
- let _p = tracing::info_span!("notable_traits_in_deps", ?krate).entered();
- Arc::from_iter(
- db.transitive_deps(krate).into_iter().filter_map(|krate| db.crate_notable_traits(krate)),
- )
-}
-
-pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Arc<[TraitId]>> {
- let _p = tracing::info_span!("crate_notable_traits", ?krate).entered();
-
+#[salsa::tracked(returns(as_deref))]
+pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Box<[TraitId]>> {
let mut traits = Vec::new();
let crate_def_map = crate_def_map(db, krate);
diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs
index 522d12d012..aebb6def93 100644
--- a/crates/hir-ty/src/drop.rs
+++ b/crates/hir-ty/src/drop.rs
@@ -28,10 +28,10 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
};
let impls = match module.containing_block() {
Some(block) => match TraitImpls::for_block(db, block) {
- Some(it) => it,
+ Some(it) => &**it,
None => return false,
},
- None => &**TraitImpls::for_crate(db, module.krate()),
+ None => TraitImpls::for_crate(db, module.krate()),
};
!impls.for_trait_and_self_ty(drop_trait, &SimplifiedType::Adt(adt.into())).is_empty()
}
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 799bfb3b4d..59299f2c35 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -687,7 +687,7 @@ impl TraitImpls {
#[salsa::tracked(returns(ref))]
pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc<Self>]> {
- db.transitive_deps(krate).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect()
+ krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect()
}
}
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index e98e5e4828..a381f929e8 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -613,6 +613,7 @@ fn main() {
"impl_signature_with_source_map_shim",
"callable_item_signature_shim",
"TraitImpls::for_crate_and_deps_",
+ "Crate::transitive_deps_",
"TraitImpls::for_crate_",
"impl_trait_with_diagnostics_shim",
"impl_self_ty_with_diagnostics_shim",
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 82c6cf7442..b2fa4b6b20 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -250,6 +250,14 @@ impl Crate {
db.transitive_rev_deps(self.id).into_iter().map(|id| Crate { id })
}
+ pub fn notable_traits_in_deps(self, db: &dyn HirDatabase) -> impl Iterator<Item = &TraitId> {
+ self.id
+ .transitive_deps(db)
+ .into_iter()
+ .filter_map(|&krate| db.crate_notable_traits(krate))
+ .flatten()
+ }
+
pub fn root_module(self) -> Module {
Module { id: CrateRootModuleId::from(self.id).into() }
}
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index e1d18b0c41..fa4b4b6d24 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -8,7 +8,6 @@ use std::{iter, ops::Not};
use either::Either;
use hir::{
DisplayTarget, GenericDef, GenericSubstitution, HasCrate, HasSource, LangItem, Semantics,
- db::DefDatabase,
};
use ide_db::{
FileRange, FxIndexSet, MiniCore, Ranker, RootDatabase,
@@ -522,9 +521,8 @@ fn notable_traits<'db>(
return Vec::new();
}
- db.notable_traits_in_deps(ty.krate(db).into())
- .iter()
- .flat_map(|it| &**it)
+ ty.krate(db)
+ .notable_traits_in_deps(db)
.filter_map(move |&trait_| {
let trait_ = trait_.into();
ty.impls_trait(db, trait_, &[]).then(|| {