mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2026-01-17 17:12:14 +00:00
Turn transitive dependencies into a query
This commit is contained in:
parent
782cda9969
commit
66b6a1e474
@ -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>>);
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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() }
|
||||
}
|
||||
|
||||
@ -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(|| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user