1 //! The home of `HirDatabase`, which is the Salsa database containing all the
2 //! type inference-related queries.
6 use arrayvec::ArrayVec;
7 use base_db::{impl_intern_key, salsa, CrateId, Upcast};
9 db::DefDatabase, expr::ExprId, BlockId, ConstId, ConstParamId, DefWithBodyId, FunctionId,
10 GenericDefId, ImplId, LifetimeParamId, LocalFieldId, TypeOrConstParamId, VariantId,
12 use la_arena::ArenaMap;
16 consteval::{ComputedExpr, ConstEvalError},
17 method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
18 Binders, CallableDefId, FnDefId, GenericArg, ImplTraitId, InferenceResult, Interner, PolyFnSig,
19 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
21 use hir_expand::name::Name;
23 #[salsa::query_group(HirDatabaseStorage)]
24 pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
25 #[salsa::invoke(infer_wait)]
27 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
29 #[salsa::invoke(crate::infer::infer_query)]
30 fn infer_query(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
32 #[salsa::invoke(crate::lower::ty_query)]
33 #[salsa::cycle(crate::lower::ty_recover)]
34 fn ty(&self, def: TyDefId) -> Binders<Ty>;
36 #[salsa::invoke(crate::lower::value_ty_query)]
37 fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
39 #[salsa::invoke(crate::lower::impl_self_ty_query)]
40 #[salsa::cycle(crate::lower::impl_self_ty_recover)]
41 fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
43 #[salsa::invoke(crate::lower::const_param_ty_query)]
44 fn const_param_ty(&self, def: ConstParamId) -> Ty;
46 #[salsa::invoke(crate::consteval::const_eval_query)]
47 #[salsa::cycle(crate::consteval::const_eval_recover)]
48 fn const_eval(&self, def: ConstId) -> Result<ComputedExpr, ConstEvalError>;
50 #[salsa::invoke(crate::lower::impl_trait_query)]
51 fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
53 #[salsa::invoke(crate::lower::field_types_query)]
54 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>>;
56 #[salsa::invoke(crate::lower::callable_item_sig)]
57 fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
59 #[salsa::invoke(crate::lower::return_type_impl_traits)]
60 fn return_type_impl_traits(
63 ) -> Option<Arc<Binders<ReturnTypeImplTraits>>>;
65 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
66 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
67 fn generic_predicates_for_param(
70 param_id: TypeOrConstParamId,
71 assoc_name: Option<Name>,
72 ) -> Arc<[Binders<QuantifiedWhereClause>]>;
74 #[salsa::invoke(crate::lower::generic_predicates_query)]
75 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<QuantifiedWhereClause>]>;
77 #[salsa::invoke(crate::lower::trait_environment_query)]
78 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
80 #[salsa::invoke(crate::lower::generic_defaults_query)]
81 #[salsa::cycle(crate::lower::generic_defaults_recover)]
82 fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<GenericArg>]>;
84 #[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
85 fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
87 #[salsa::invoke(InherentImpls::inherent_impls_in_block_query)]
88 fn inherent_impls_in_block(&self, block: BlockId) -> Option<Arc<InherentImpls>>;
90 /// Collects all crates in the dependency graph that have impls for the
91 /// given fingerprint. This is only used for primitive types; for
92 /// user-defined types we just look at the crate where the type is defined.
93 #[salsa::invoke(crate::method_resolution::inherent_impl_crates_query)]
94 fn inherent_impl_crates(&self, krate: CrateId, fp: TyFingerprint) -> ArrayVec<CrateId, 2>;
96 #[salsa::invoke(TraitImpls::trait_impls_in_crate_query)]
97 fn trait_impls_in_crate(&self, krate: CrateId) -> Arc<TraitImpls>;
99 #[salsa::invoke(TraitImpls::trait_impls_in_block_query)]
100 fn trait_impls_in_block(&self, krate: BlockId) -> Option<Arc<TraitImpls>>;
102 #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
103 fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<TraitImpls>;
105 // Interned IDs for Chalk integration
107 fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId;
109 fn intern_type_or_const_param_id(
111 param_id: TypeOrConstParamId,
112 ) -> InternedTypeOrConstParamId;
114 fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId;
116 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
118 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
120 #[salsa::invoke(chalk_db::associated_ty_data_query)]
121 fn associated_ty_data(&self, id: chalk_db::AssocTypeId) -> Arc<chalk_db::AssociatedTyDatum>;
123 #[salsa::invoke(chalk_db::trait_datum_query)]
124 fn trait_datum(&self, krate: CrateId, trait_id: chalk_db::TraitId)
125 -> Arc<chalk_db::TraitDatum>;
127 #[salsa::invoke(chalk_db::struct_datum_query)]
131 struct_id: chalk_db::AdtId,
132 ) -> Arc<chalk_db::StructDatum>;
134 #[salsa::invoke(chalk_db::impl_datum_query)]
135 fn impl_datum(&self, krate: CrateId, impl_id: chalk_db::ImplId) -> Arc<chalk_db::ImplDatum>;
137 #[salsa::invoke(chalk_db::fn_def_datum_query)]
138 fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk_db::FnDefDatum>;
140 #[salsa::invoke(chalk_db::fn_def_variance_query)]
141 fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances;
143 #[salsa::invoke(chalk_db::adt_variance_query)]
144 fn adt_variance(&self, adt_id: chalk_db::AdtId) -> chalk_db::Variances;
146 #[salsa::invoke(chalk_db::associated_ty_value_query)]
147 fn associated_ty_value(
150 id: chalk_db::AssociatedTyValueId,
151 ) -> Arc<chalk_db::AssociatedTyValue>;
153 #[salsa::invoke(trait_solve_wait)]
154 #[salsa::transparent]
158 goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
159 ) -> Option<crate::Solution>;
161 #[salsa::invoke(crate::traits::trait_solve_query)]
162 fn trait_solve_query(
165 goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
166 ) -> Option<crate::Solution>;
168 #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)]
169 fn program_clauses_for_chalk_env(
172 env: chalk_ir::Environment<Interner>,
173 ) -> chalk_ir::ProgramClauses<Interner>;
176 fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
177 let _p = profile::span("infer:wait").detail(|| match def {
178 DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(),
179 DefWithBodyId::StaticId(it) => db.static_data(it).name.clone().to_string(),
180 DefWithBodyId::ConstId(it) => {
181 db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string()
188 db: &dyn HirDatabase,
190 goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
191 ) -> Option<crate::Solution> {
192 let _p = profile::span("trait_solve::wait");
193 db.trait_solve_query(krate, goal)
197 fn hir_database_is_object_safe() {
198 fn _assert_object_safe(_: &dyn HirDatabase) {}
201 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
202 pub struct InternedTypeOrConstParamId(salsa::InternId);
203 impl_intern_key!(InternedTypeOrConstParamId);
205 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
206 pub struct InternedLifetimeParamId(salsa::InternId);
207 impl_intern_key!(InternedLifetimeParamId);
209 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
210 pub struct InternedConstParamId(salsa::InternId);
211 impl_intern_key!(InternedConstParamId);
213 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
214 pub struct InternedOpaqueTyId(salsa::InternId);
215 impl_intern_key!(InternedOpaqueTyId);
217 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
218 pub struct InternedClosureId(salsa::InternId);
219 impl_intern_key!(InternedClosureId);
221 /// This exists just for Chalk, because Chalk just has a single `FnDefId` where
222 /// we have different IDs for struct and enum variant constructors.
223 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
224 pub struct InternedCallableDefId(salsa::InternId);
225 impl_intern_key!(InternedCallableDefId);