hir_ty/
db.rs

1//! The home of `HirDatabase`, which is the Salsa database containing all the
2//! type inference-related queries.
3
4use base_db::Crate;
5use hir_def::{
6    AdtId, BlockId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
7    GeneralConstId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId,
8    TypeAliasId, TypeOrConstParamId, VariantId, db::DefDatabase, hir::ExprId,
9    layout::TargetDataLayout,
10};
11use hir_expand::name::Name;
12use la_arena::ArenaMap;
13use salsa::plumbing::AsId;
14use smallvec::SmallVec;
15use triomphe::Arc;
16
17use crate::{
18    Binders, Const, ImplTraitId, ImplTraits, InferenceResult, PolyFnSig, Substitution,
19    TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId, chalk_db,
20    consteval::ConstEvalError,
21    drop::DropGlue,
22    dyn_compatibility::DynCompatibilityViolation,
23    layout::{Layout, LayoutError},
24    lower::{Diagnostics, GenericDefaults, GenericPredicates},
25    method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
26    mir::{BorrowckResult, MirBody, MirLowerError},
27    traits::NextTraitSolveResult,
28};
29
30#[query_group::query_group]
31pub trait HirDatabase: DefDatabase + std::fmt::Debug {
32    #[salsa::invoke(crate::infer::infer_query)]
33    #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
34    fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
35
36    // region:mir
37
38    #[salsa::invoke(crate::mir::mir_body_query)]
39    #[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)]
40    fn mir_body(&self, def: DefWithBodyId) -> Result<Arc<MirBody>, MirLowerError>;
41
42    #[salsa::invoke(crate::mir::mir_body_for_closure_query)]
43    fn mir_body_for_closure(&self, def: InternedClosureId) -> Result<Arc<MirBody>, MirLowerError>;
44
45    #[salsa::invoke(crate::mir::monomorphized_mir_body_query)]
46    #[salsa::cycle(cycle_result = crate::mir::monomorphized_mir_body_cycle_result)]
47    fn monomorphized_mir_body(
48        &self,
49        def: DefWithBodyId,
50        subst: Substitution,
51        env: Arc<TraitEnvironment>,
52    ) -> Result<Arc<MirBody>, MirLowerError>;
53
54    #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)]
55    fn monomorphized_mir_body_for_closure(
56        &self,
57        def: InternedClosureId,
58        subst: Substitution,
59        env: Arc<TraitEnvironment>,
60    ) -> Result<Arc<MirBody>, MirLowerError>;
61
62    #[salsa::invoke(crate::mir::borrowck_query)]
63    #[salsa::lru(2024)]
64    fn borrowck(&self, def: DefWithBodyId) -> Result<Arc<[BorrowckResult]>, MirLowerError>;
65
66    #[salsa::invoke(crate::consteval::const_eval_query)]
67    #[salsa::cycle(cycle_result = crate::consteval::const_eval_cycle_result)]
68    fn const_eval(
69        &self,
70        def: GeneralConstId,
71        subst: Substitution,
72        trait_env: Option<Arc<TraitEnvironment>>,
73    ) -> Result<Const, ConstEvalError>;
74
75    #[salsa::invoke(crate::consteval::const_eval_static_query)]
76    #[salsa::cycle(cycle_result = crate::consteval::const_eval_static_cycle_result)]
77    fn const_eval_static(&self, def: StaticId) -> Result<Const, ConstEvalError>;
78
79    #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)]
80    #[salsa::cycle(cycle_result = crate::consteval::const_eval_discriminant_cycle_result)]
81    fn const_eval_discriminant(&self, def: EnumVariantId) -> Result<i128, ConstEvalError>;
82
83    #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
84    fn lookup_impl_method(
85        &self,
86        env: Arc<TraitEnvironment>,
87        func: FunctionId,
88        fn_subst: Substitution,
89    ) -> (FunctionId, Substitution);
90
91    // endregion:mir
92
93    #[salsa::invoke(crate::layout::layout_of_adt_query)]
94    #[salsa::cycle(cycle_result = crate::layout::layout_of_adt_cycle_result)]
95    fn layout_of_adt<'db>(
96        &'db self,
97        def: AdtId,
98        args: crate::next_solver::GenericArgs<'db>,
99        trait_env: Arc<TraitEnvironment>,
100    ) -> Result<Arc<Layout>, LayoutError>;
101
102    #[salsa::invoke(crate::layout::layout_of_ty_query)]
103    #[salsa::cycle(cycle_result = crate::layout::layout_of_ty_cycle_result)]
104    fn layout_of_ty<'db>(
105        &'db self,
106        ty: crate::next_solver::Ty<'db>,
107        env: Arc<TraitEnvironment>,
108    ) -> Result<Arc<Layout>, LayoutError>;
109
110    #[salsa::invoke(crate::layout::target_data_layout_query)]
111    fn target_data_layout(&self, krate: Crate) -> Result<Arc<TargetDataLayout>, Arc<str>>;
112
113    #[salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)]
114    fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option<DynCompatibilityViolation>;
115
116    #[salsa::invoke(crate::lower::ty_query)]
117    #[salsa::transparent]
118    fn ty(&self, def: TyDefId) -> Binders<Ty>;
119
120    #[salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics_query)]
121    #[salsa::cycle(cycle_result = crate::lower::type_for_type_alias_with_diagnostics_cycle_result)]
122    fn type_for_type_alias_with_diagnostics(&self, def: TypeAliasId) -> (Binders<Ty>, Diagnostics);
123
124    /// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is
125    /// a `StructId` or `EnumVariantId` with a record constructor.
126    #[salsa::invoke(crate::lower::value_ty_query)]
127    fn value_ty(&self, def: ValueTyDefId) -> Option<Binders<Ty>>;
128
129    #[salsa::invoke(crate::lower::impl_self_ty_with_diagnostics_query)]
130    #[salsa::cycle(cycle_result = crate::lower::impl_self_ty_with_diagnostics_cycle_result)]
131    fn impl_self_ty_with_diagnostics(&self, def: ImplId) -> (Binders<Ty>, Diagnostics);
132
133    #[salsa::invoke(crate::lower::impl_self_ty_query)]
134    #[salsa::transparent]
135    fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
136
137    // FIXME: Make this a non-interned query.
138    #[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
139    #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
140    fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics);
141
142    #[salsa::invoke(crate::lower::const_param_ty_query)]
143    #[salsa::transparent]
144    fn const_param_ty(&self, def: ConstParamId) -> Ty;
145
146    #[salsa::invoke(crate::lower::impl_trait_with_diagnostics_query)]
147    fn impl_trait_with_diagnostics(&self, def: ImplId) -> Option<(Binders<TraitRef>, Diagnostics)>;
148
149    #[salsa::invoke(crate::lower::impl_trait_query)]
150    #[salsa::transparent]
151    fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
152
153    #[salsa::invoke(crate::lower::field_types_with_diagnostics_query)]
154    fn field_types_with_diagnostics(
155        &self,
156        var: VariantId,
157    ) -> (Arc<ArenaMap<LocalFieldId, Binders<Ty>>>, Diagnostics);
158
159    #[salsa::invoke(crate::lower::field_types_query)]
160    #[salsa::transparent]
161    fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>>;
162
163    #[salsa::invoke(crate::lower::callable_item_signature_query)]
164    fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
165
166    #[salsa::invoke(crate::lower::return_type_impl_traits)]
167    fn return_type_impl_traits(&self, def: FunctionId) -> Option<Arc<Binders<ImplTraits>>>;
168
169    #[salsa::invoke(crate::lower::type_alias_impl_traits)]
170    fn type_alias_impl_traits(&self, def: TypeAliasId) -> Option<Arc<Binders<ImplTraits>>>;
171
172    #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
173    #[salsa::cycle(cycle_result = crate::lower::generic_predicates_for_param_cycle_result)]
174    fn generic_predicates_for_param(
175        &self,
176        def: GenericDefId,
177        param_id: TypeOrConstParamId,
178        assoc_name: Option<Name>,
179    ) -> GenericPredicates;
180
181    #[salsa::invoke(crate::lower::generic_predicates_query)]
182    fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
183
184    #[salsa::invoke(crate::lower::trait_environment_for_body_query)]
185    #[salsa::transparent]
186    fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
187
188    #[salsa::invoke(crate::lower::trait_environment_query)]
189    fn trait_environment(&self, def: GenericDefId) -> Arc<TraitEnvironment>;
190
191    #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)]
192    #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)]
193    fn generic_defaults_with_diagnostics(
194        &self,
195        def: GenericDefId,
196    ) -> (GenericDefaults, Diagnostics);
197
198    /// This returns an empty list if no parameter has default.
199    ///
200    /// The binders of the returned defaults are only up to (not including) this parameter.
201    #[salsa::invoke(crate::lower::generic_defaults_query)]
202    #[salsa::transparent]
203    fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
204
205    #[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
206    fn inherent_impls_in_crate(&self, krate: Crate) -> Arc<InherentImpls>;
207
208    #[salsa::invoke(InherentImpls::inherent_impls_in_block_query)]
209    fn inherent_impls_in_block(&self, block: BlockId) -> Option<Arc<InherentImpls>>;
210
211    /// Collects all crates in the dependency graph that have impls for the
212    /// given fingerprint. This is only used for primitive types and types
213    /// annotated with `rustc_has_incoherent_inherent_impls`; for other types
214    /// we just look at the crate where the type is defined.
215    #[salsa::invoke(crate::method_resolution::incoherent_inherent_impl_crates)]
216    fn incoherent_inherent_impl_crates(
217        &self,
218        krate: Crate,
219        fp: TyFingerprint,
220    ) -> SmallVec<[Crate; 2]>;
221
222    #[salsa::invoke(TraitImpls::trait_impls_in_crate_query)]
223    fn trait_impls_in_crate(&self, krate: Crate) -> Arc<TraitImpls>;
224
225    #[salsa::invoke(TraitImpls::trait_impls_in_block_query)]
226    fn trait_impls_in_block(&self, block: BlockId) -> Option<Arc<TraitImpls>>;
227
228    #[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
229    fn trait_impls_in_deps(&self, krate: Crate) -> Arc<[Arc<TraitImpls>]>;
230
231    // Interned IDs for Chalk integration
232    #[salsa::interned]
233    fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
234
235    #[salsa::interned]
236    fn intern_closure(&self, id: InternedClosure) -> InternedClosureId;
237
238    #[salsa::interned]
239    fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId;
240
241    #[salsa::invoke(chalk_db::fn_def_variance_query)]
242    fn fn_def_variance(&self, fn_def_id: CallableDefId) -> chalk_db::Variances;
243
244    #[salsa::invoke(chalk_db::adt_variance_query)]
245    fn adt_variance(&self, adt_id: AdtId) -> chalk_db::Variances;
246
247    #[salsa::invoke(crate::variance::variances_of)]
248    #[salsa::cycle(
249        // cycle_fn = crate::variance::variances_of_cycle_fn,
250        // cycle_initial = crate::variance::variances_of_cycle_initial,
251        cycle_result = crate::variance::variances_of_cycle_initial,
252    )]
253    fn variances_of(&self, def: GenericDefId) -> Option<Arc<[crate::variance::Variance]>>;
254
255    #[salsa::invoke(crate::traits::normalize_projection_query)]
256    #[salsa::transparent]
257    fn normalize_projection(
258        &self,
259        projection: crate::ProjectionTy,
260        env: Arc<TraitEnvironment>,
261    ) -> Ty;
262
263    #[salsa::invoke(crate::traits::trait_solve_query)]
264    #[salsa::transparent]
265    fn trait_solve(
266        &self,
267        krate: Crate,
268        block: Option<BlockId>,
269        goal: crate::Canonical<crate::InEnvironment<crate::Goal>>,
270    ) -> NextTraitSolveResult;
271
272    #[salsa::invoke(crate::drop::has_drop_glue)]
273    #[salsa::cycle(cycle_result = crate::drop::has_drop_glue_cycle_result)]
274    fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment>) -> DropGlue;
275
276    // next trait solver
277
278    #[salsa::invoke(crate::lower_nextsolver::ty_query)]
279    #[salsa::transparent]
280    fn ty_ns<'db>(
281        &'db self,
282        def: TyDefId,
283    ) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
284
285    #[salsa::invoke(crate::lower_nextsolver::type_for_type_alias_with_diagnostics_query)]
286    #[salsa::cycle(cycle_result = crate::lower_nextsolver::type_for_type_alias_with_diagnostics_cycle_result)]
287    fn type_for_type_alias_with_diagnostics_ns<'db>(
288        &'db self,
289        def: TypeAliasId,
290    ) -> (crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>, Diagnostics);
291
292    #[salsa::invoke(crate::lower_nextsolver::impl_self_ty_with_diagnostics_query)]
293    #[salsa::cycle(cycle_result = crate::lower_nextsolver::impl_self_ty_with_diagnostics_cycle_result)]
294    fn impl_self_ty_with_diagnostics_ns<'db>(
295        &'db self,
296        def: ImplId,
297    ) -> (crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>, Diagnostics);
298
299    #[salsa::invoke(crate::lower_nextsolver::impl_self_ty_query)]
300    #[salsa::transparent]
301    fn impl_self_ty_ns<'db>(
302        &'db self,
303        def: ImplId,
304    ) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
305
306    // FIXME: Make this a non-interned query.
307    #[salsa::invoke_interned(crate::lower_nextsolver::const_param_ty_with_diagnostics_query)]
308    fn const_param_ty_with_diagnostics_ns<'db>(
309        &'db self,
310        def: ConstParamId,
311    ) -> (crate::next_solver::Ty<'db>, Diagnostics);
312
313    #[salsa::invoke(crate::lower_nextsolver::const_param_ty_query)]
314    #[salsa::transparent]
315    fn const_param_ty_ns<'db>(&'db self, def: ConstParamId) -> crate::next_solver::Ty<'db>;
316
317    #[salsa::invoke(crate::lower_nextsolver::impl_trait_with_diagnostics_query)]
318    fn impl_trait_with_diagnostics_ns<'db>(
319        &'db self,
320        def: ImplId,
321    ) -> Option<(
322        crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>,
323        Diagnostics,
324    )>;
325
326    #[salsa::invoke(crate::lower_nextsolver::impl_trait_query)]
327    #[salsa::transparent]
328    fn impl_trait_ns<'db>(
329        &'db self,
330        def: ImplId,
331    ) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>>;
332
333    #[salsa::invoke(crate::lower_nextsolver::field_types_with_diagnostics_query)]
334    fn field_types_with_diagnostics_ns<'db>(
335        &'db self,
336        var: VariantId,
337    ) -> (
338        Arc<
339            ArenaMap<
340                LocalFieldId,
341                crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>,
342            >,
343        >,
344        Diagnostics,
345    );
346
347    #[salsa::invoke(crate::lower_nextsolver::field_types_query)]
348    #[salsa::transparent]
349    fn field_types_ns<'db>(
350        &'db self,
351        var: VariantId,
352    ) -> Arc<
353        ArenaMap<LocalFieldId, crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>>,
354    >;
355
356    #[salsa::invoke(crate::lower_nextsolver::callable_item_signature_query)]
357    fn callable_item_signature_ns<'db>(
358        &'db self,
359        def: CallableDefId,
360    ) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::PolyFnSig<'db>>;
361
362    #[salsa::invoke(crate::lower_nextsolver::return_type_impl_traits)]
363    fn return_type_impl_traits_ns<'db>(
364        &'db self,
365        def: FunctionId,
366    ) -> Option<Arc<crate::next_solver::EarlyBinder<'db, crate::lower_nextsolver::ImplTraits<'db>>>>;
367
368    #[salsa::invoke(crate::lower_nextsolver::type_alias_impl_traits)]
369    fn type_alias_impl_traits_ns<'db>(
370        &'db self,
371        def: TypeAliasId,
372    ) -> Option<Arc<crate::next_solver::EarlyBinder<'db, crate::lower_nextsolver::ImplTraits<'db>>>>;
373
374    #[salsa::invoke(crate::lower_nextsolver::generic_predicates_for_param_query)]
375    #[salsa::cycle(cycle_result = crate::lower_nextsolver::generic_predicates_for_param_cycle_result)]
376    fn generic_predicates_for_param_ns<'db>(
377        &'db self,
378        def: GenericDefId,
379        param_id: TypeOrConstParamId,
380        assoc_name: Option<Name>,
381    ) -> crate::lower_nextsolver::GenericPredicates<'db>;
382
383    #[salsa::invoke(crate::lower_nextsolver::generic_predicates_query)]
384    fn generic_predicates_ns<'db>(
385        &'db self,
386        def: GenericDefId,
387    ) -> crate::lower_nextsolver::GenericPredicates<'db>;
388
389    #[salsa::invoke(
390        crate::lower_nextsolver::generic_predicates_without_parent_with_diagnostics_query
391    )]
392    fn generic_predicates_without_parent_with_diagnostics_ns<'db>(
393        &'db self,
394        def: GenericDefId,
395    ) -> (crate::lower_nextsolver::GenericPredicates<'db>, Diagnostics);
396
397    #[salsa::invoke(crate::lower_nextsolver::generic_predicates_without_parent_query)]
398    #[salsa::transparent]
399    fn generic_predicates_without_parent_ns<'db>(
400        &'db self,
401        def: GenericDefId,
402    ) -> crate::lower_nextsolver::GenericPredicates<'db>;
403}
404
405#[test]
406fn hir_database_is_dyn_compatible() {
407    fn _assert_dyn_compatible(_: &dyn HirDatabase) {}
408}
409
410#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
411#[derive(PartialOrd, Ord)]
412pub struct InternedTypeOrConstParamId {
413    /// This stores the param and its index.
414    pub loc: (TypeOrConstParamId, u32),
415}
416
417#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
418#[derive(PartialOrd, Ord)]
419pub struct InternedLifetimeParamId {
420    /// This stores the param and its index.
421    pub loc: (LifetimeParamId, u32),
422}
423
424#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
425#[derive(PartialOrd, Ord)]
426pub struct InternedConstParamId {
427    pub loc: ConstParamId,
428}
429
430#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
431#[derive(PartialOrd, Ord)]
432pub struct InternedOpaqueTyId {
433    pub loc: ImplTraitId,
434}
435
436#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
437pub struct InternedClosure(pub DefWithBodyId, pub ExprId);
438
439#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
440#[derive(PartialOrd, Ord)]
441pub struct InternedClosureId {
442    pub loc: InternedClosure,
443}
444
445#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
446pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId);
447
448#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
449#[derive(PartialOrd, Ord)]
450pub struct InternedCoroutineId {
451    pub loc: InternedCoroutine,
452}