Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 55 additions & 27 deletions crates/base-db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,61 @@ pub struct Crate {
pub env: Env,
}

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.
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()
}

/// Returns all transitive reverse 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.
pub fn transitive_rev_deps(self, db: &dyn RootQueryDb) -> Box<[Crate]> {
let mut worklist = vec![self];
let mut rev_deps = FxHashSet::default();
rev_deps.insert(self);

let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
db.all_crates().iter().for_each(|&krate| {
krate
.data(db)
.dependencies
.iter()
.for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate))
});

while let Some(krate) = worklist.pop() {
if let Some(crate_rev_deps) = inverted_graph.get(&krate) {
crate_rev_deps
.iter()
.copied()
.filter(|&rev_dep| rev_deps.insert(rev_dep))
.for_each(|rev_dep| worklist.push(rev_dep));
}
}

rev_deps.into_iter().collect::<Box<_>>()
}
}

/// The mapping from [`UniqueCrateData`] to their [`Crate`] input.
#[derive(Debug, Default)]
pub struct CratesMap(DashMap<UniqueCrateData, Crate, BuildHasherDefault<FxHasher>>);
Expand Down Expand Up @@ -802,33 +857,6 @@ impl CrateGraphBuilder {
}
}

pub(crate) fn transitive_rev_deps(db: &dyn RootQueryDb, of: Crate) -> FxHashSet<Crate> {
let mut worklist = vec![of];
let mut rev_deps = FxHashSet::default();
rev_deps.insert(of);

let mut inverted_graph = FxHashMap::<_, Vec<_>>::default();
db.all_crates().iter().for_each(|&krate| {
krate
.data(db)
.dependencies
.iter()
.for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate))
});

while let Some(krate) = worklist.pop() {
if let Some(crate_rev_deps) = inverted_graph.get(&krate) {
crate_rev_deps
.iter()
.copied()
.filter(|&rev_dep| rev_deps.insert(rev_dep))
.for_each(|rev_dep| worklist.push(rev_dep));
}
}

rev_deps
}

impl BuiltCrateData {
pub fn root_file_id(&self, db: &dyn salsa::Database) -> EditionedFileId {
EditionedFileId::new(db, self.root_file_id, self.edition)
Expand Down
34 changes: 1 addition & 33 deletions crates/base-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use crate::{
};
use dashmap::{DashMap, mapref::entry::Entry};
pub use query_group::{self};
use rustc_hash::{FxHashSet, FxHasher};
use rustc_hash::FxHasher;
use salsa::{Durability, Setter};
pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
use span::Edition;
Expand Down Expand Up @@ -256,38 +256,6 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
#[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.
///
/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
#[salsa::invoke(input::transitive_rev_deps)]
#[salsa::transparent]
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]
Expand Down
5 changes: 2 additions & 3 deletions crates/hir-def/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 2 additions & 11 deletions crates/hir-def/src/lang_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
60 changes: 28 additions & 32 deletions crates/hir-ty/src/consteval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod tests;

use base_db::Crate;
use hir_def::{
EnumVariantId, GeneralConstId, HasModule, StaticId,
ConstId, EnumVariantId, StaticId,
expr_store::Body,
hir::{Expr, ExprId},
type_ref::LiteralConstRef,
Expand Down Expand Up @@ -139,16 +139,18 @@ pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u
ConstKind::Infer(_) => None,
ConstKind::Bound(_, _) => None,
ConstKind::Placeholder(_) => None,
ConstKind::Unevaluated(unevaluated_const) => {
let c = match unevaluated_const.def {
SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
_ => unreachable!(),
};
let subst = unevaluated_const.args;
let ec = db.const_eval(c, subst, None).ok()?;
try_const_usize(db, ec)
}
ConstKind::Unevaluated(unevaluated_const) => match unevaluated_const.def {
SolverDefId::ConstId(id) => {
let subst = unevaluated_const.args;
let ec = db.const_eval(id, subst, None).ok()?;
try_const_usize(db, ec)
}
SolverDefId::StaticId(id) => {
let ec = db.const_eval_static(id).ok()?;
try_const_usize(db, ec)
}
_ => unreachable!(),
},
ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().memory, false))),
ConstKind::Error(_) => None,
ConstKind::Expr(_) => None,
Expand All @@ -161,16 +163,18 @@ pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<
ConstKind::Infer(_) => None,
ConstKind::Bound(_, _) => None,
ConstKind::Placeholder(_) => None,
ConstKind::Unevaluated(unevaluated_const) => {
let c = match unevaluated_const.def {
SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
_ => unreachable!(),
};
let subst = unevaluated_const.args;
let ec = db.const_eval(c, subst, None).ok()?;
try_const_isize(db, &ec)
}
ConstKind::Unevaluated(unevaluated_const) => match unevaluated_const.def {
SolverDefId::ConstId(id) => {
let subst = unevaluated_const.args;
let ec = db.const_eval(id, subst, None).ok()?;
try_const_isize(db, &ec)
}
SolverDefId::StaticId(id) => {
let ec = db.const_eval_static(id).ok()?;
try_const_isize(db, &ec)
}
_ => unreachable!(),
},
ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().memory, true))),
ConstKind::Error(_) => None,
ConstKind::Expr(_) => None,
Expand Down Expand Up @@ -254,7 +258,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd

pub(crate) fn const_eval_cycle_result<'db>(
_: &'db dyn HirDatabase,
_: GeneralConstId,
_: ConstId,
_: GenericArgs<'db>,
_: Option<Arc<TraitEnvironment<'db>>>,
) -> Result<Const<'db>, ConstEvalError<'db>> {
Expand All @@ -277,19 +281,11 @@ pub(crate) fn const_eval_discriminant_cycle_result<'db>(

pub(crate) fn const_eval_query<'db>(
db: &'db dyn HirDatabase,
def: GeneralConstId,
def: ConstId,
subst: GenericArgs<'db>,
trait_env: Option<Arc<TraitEnvironment<'db>>>,
) -> Result<Const<'db>, ConstEvalError<'db>> {
let body = match def {
GeneralConstId::ConstId(c) => {
db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))?
}
GeneralConstId::StaticId(s) => {
let krate = s.module(db).krate();
db.monomorphized_mir_body(s.into(), subst, TraitEnvironment::empty(krate))?
}
};
let body = db.monomorphized_mir_body(def.into(), subst, db.trait_environment(def.into()))?;
let c = interpret_mir(db, body, false, trait_env)?.0?;
Ok(c)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEv
_ => None,
})
.expect("No const named GOAL found in the test");
db.const_eval(const_id.into(), GenericArgs::new_from_iter(interner, []), None)
db.const_eval(const_id, GenericArgs::new_from_iter(interner, []), None)
}

#[test]
Expand Down
17 changes: 6 additions & 11 deletions crates/hir-ty/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

use base_db::{Crate, target::TargetLoadError};
use hir_def::{
AdtId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId,
GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId,
TypeOrConstParamId, VariantId, db::DefDatabase, hir::ExprId, layout::TargetDataLayout,
AdtId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, VariantId,
db::DefDatabase, hir::ExprId, layout::TargetDataLayout,
};
use la_arena::ArenaMap;
use salsa::plumbing::AsId;
Expand All @@ -29,6 +29,8 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {

// region:mir

// FXME: Collapse `mir_body_for_closure` into `mir_body`
// and `monomorphized_mir_body_for_closure` into `monomorphized_mir_body`
#[salsa::invoke(crate::mir::mir_body_query)]
#[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)]
fn mir_body<'db>(
Expand Down Expand Up @@ -70,7 +72,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
#[salsa::cycle(cycle_result = crate::consteval::const_eval_cycle_result)]
fn const_eval<'db>(
&'db self,
def: GeneralConstId,
def: ConstId,
subst: GenericArgs<'db>,
trait_env: Option<Arc<TraitEnvironment<'db>>>,
) -> Result<Const<'db>, ConstEvalError<'db>>;
Expand Down Expand Up @@ -232,13 +234,6 @@ fn hir_database_is_dyn_compatible() {
fn _assert_dyn_compatible(_: &dyn HirDatabase) {}
}

#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
#[derive(PartialOrd, Ord)]
pub struct InternedTypeOrConstParamId {
/// This stores the param and its index.
pub loc: (TypeOrConstParamId, u32),
}

#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
#[derive(PartialOrd, Ord)]
pub struct InternedLifetimeParamId {
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
Loading