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, target::TargetLoadError};
5use hir_def::{
6    AdtId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
7    GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, VariantId,
8    db::DefDatabase, hir::ExprId, layout::TargetDataLayout,
9};
10use la_arena::ArenaMap;
11use salsa::plumbing::AsId;
12use triomphe::Arc;
13
14use crate::{
15    ImplTraitId, TyDefId, ValueTyDefId,
16    consteval::ConstEvalError,
17    dyn_compatibility::DynCompatibilityViolation,
18    layout::{Layout, LayoutError},
19    lower::{Diagnostics, GenericDefaults},
20    mir::{BorrowckResult, MirBody, MirLowerError},
21    next_solver::{
22        Const, EarlyBinder, GenericArgs, ParamEnv, PolyFnSig, TraitRef, Ty, VariancesOf,
23    },
24    traits::ParamEnvAndCrate,
25};
26
27#[query_group::query_group]
28pub trait HirDatabase: DefDatabase + std::fmt::Debug {
29    // region:mir
30
31    // FXME: Collapse `mir_body_for_closure` into `mir_body`
32    // and `monomorphized_mir_body_for_closure` into `monomorphized_mir_body`
33    #[salsa::invoke(crate::mir::mir_body_query)]
34    #[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)]
35    fn mir_body<'db>(
36        &'db self,
37        def: DefWithBodyId,
38    ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
39
40    #[salsa::invoke(crate::mir::mir_body_for_closure_query)]
41    fn mir_body_for_closure<'db>(
42        &'db self,
43        def: InternedClosureId,
44    ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
45
46    #[salsa::invoke(crate::mir::monomorphized_mir_body_query)]
47    #[salsa::cycle(cycle_result = crate::mir::monomorphized_mir_body_cycle_result)]
48    fn monomorphized_mir_body<'db>(
49        &'db self,
50        def: DefWithBodyId,
51        subst: GenericArgs<'db>,
52        env: ParamEnvAndCrate<'db>,
53    ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
54
55    #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)]
56    fn monomorphized_mir_body_for_closure<'db>(
57        &'db self,
58        def: InternedClosureId,
59        subst: GenericArgs<'db>,
60        env: ParamEnvAndCrate<'db>,
61    ) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
62
63    #[salsa::invoke(crate::mir::borrowck_query)]
64    #[salsa::lru(2024)]
65    fn borrowck<'db>(
66        &'db self,
67        def: DefWithBodyId,
68    ) -> Result<Arc<[BorrowckResult<'db>]>, MirLowerError<'db>>;
69
70    #[salsa::invoke(crate::consteval::const_eval_query)]
71    #[salsa::cycle(cycle_result = crate::consteval::const_eval_cycle_result)]
72    fn const_eval<'db>(
73        &'db self,
74        def: ConstId,
75        subst: GenericArgs<'db>,
76        trait_env: Option<ParamEnvAndCrate<'db>>,
77    ) -> Result<Const<'db>, ConstEvalError<'db>>;
78
79    #[salsa::invoke(crate::consteval::const_eval_static_query)]
80    #[salsa::cycle(cycle_result = crate::consteval::const_eval_static_cycle_result)]
81    fn const_eval_static<'db>(&'db self, def: StaticId) -> Result<Const<'db>, ConstEvalError<'db>>;
82
83    #[salsa::invoke(crate::consteval::const_eval_discriminant_variant)]
84    #[salsa::cycle(cycle_result = crate::consteval::const_eval_discriminant_cycle_result)]
85    fn const_eval_discriminant<'db>(
86        &'db self,
87        def: EnumVariantId,
88    ) -> Result<i128, ConstEvalError<'db>>;
89
90    #[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
91    #[salsa::transparent]
92    fn lookup_impl_method<'db>(
93        &'db self,
94        env: ParamEnvAndCrate<'db>,
95        func: FunctionId,
96        fn_subst: GenericArgs<'db>,
97    ) -> (FunctionId, GenericArgs<'db>);
98
99    // endregion:mir
100
101    #[salsa::invoke(crate::layout::layout_of_adt_query)]
102    #[salsa::cycle(cycle_result = crate::layout::layout_of_adt_cycle_result)]
103    fn layout_of_adt<'db>(
104        &'db self,
105        def: AdtId,
106        args: GenericArgs<'db>,
107        trait_env: ParamEnvAndCrate<'db>,
108    ) -> Result<Arc<Layout>, LayoutError>;
109
110    #[salsa::invoke(crate::layout::layout_of_ty_query)]
111    #[salsa::cycle(cycle_result = crate::layout::layout_of_ty_cycle_result)]
112    fn layout_of_ty<'db>(
113        &'db self,
114        ty: Ty<'db>,
115        env: ParamEnvAndCrate<'db>,
116    ) -> Result<Arc<Layout>, LayoutError>;
117
118    #[salsa::invoke(crate::layout::target_data_layout_query)]
119    fn target_data_layout(&self, krate: Crate) -> Result<Arc<TargetDataLayout>, TargetLoadError>;
120
121    #[salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)]
122    fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option<DynCompatibilityViolation>;
123
124    #[salsa::invoke(crate::lower::ty_query)]
125    #[salsa::transparent]
126    fn ty<'db>(&'db self, def: TyDefId) -> EarlyBinder<'db, Ty<'db>>;
127
128    #[salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics_query)]
129    #[salsa::cycle(cycle_result = crate::lower::type_for_type_alias_with_diagnostics_cycle_result)]
130    fn type_for_type_alias_with_diagnostics<'db>(
131        &'db self,
132        def: TypeAliasId,
133    ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics);
134
135    /// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is
136    /// a `StructId` or `EnumVariantId` with a record constructor.
137    #[salsa::invoke(crate::lower::value_ty_query)]
138    fn value_ty<'db>(&'db self, def: ValueTyDefId) -> Option<EarlyBinder<'db, Ty<'db>>>;
139
140    #[salsa::invoke(crate::lower::impl_self_ty_with_diagnostics_query)]
141    #[salsa::cycle(cycle_result = crate::lower::impl_self_ty_with_diagnostics_cycle_result)]
142    fn impl_self_ty_with_diagnostics<'db>(
143        &'db self,
144        def: ImplId,
145    ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics);
146
147    #[salsa::invoke(crate::lower::impl_self_ty_query)]
148    #[salsa::transparent]
149    fn impl_self_ty<'db>(&'db self, def: ImplId) -> EarlyBinder<'db, Ty<'db>>;
150
151    // FIXME: Make this a non-interned query.
152    #[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
153    #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
154    fn const_param_ty_with_diagnostics<'db>(&'db self, def: ConstParamId)
155    -> (Ty<'db>, Diagnostics);
156
157    #[salsa::invoke(crate::lower::const_param_ty_query)]
158    #[salsa::transparent]
159    fn const_param_ty_ns<'db>(&'db self, def: ConstParamId) -> Ty<'db>;
160
161    #[salsa::invoke(crate::lower::impl_trait_with_diagnostics_query)]
162    fn impl_trait_with_diagnostics<'db>(
163        &'db self,
164        def: ImplId,
165    ) -> Option<(EarlyBinder<'db, TraitRef<'db>>, Diagnostics)>;
166
167    #[salsa::invoke(crate::lower::impl_trait_query)]
168    #[salsa::transparent]
169    fn impl_trait<'db>(&'db self, def: ImplId) -> Option<EarlyBinder<'db, TraitRef<'db>>>;
170
171    #[salsa::invoke(crate::lower::field_types_with_diagnostics_query)]
172    fn field_types_with_diagnostics<'db>(
173        &'db self,
174        var: VariantId,
175    ) -> (Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>, Diagnostics);
176
177    #[salsa::invoke(crate::lower::field_types_query)]
178    #[salsa::transparent]
179    fn field_types<'db>(
180        &'db self,
181        var: VariantId,
182    ) -> Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>;
183
184    #[salsa::invoke(crate::lower::callable_item_signature_query)]
185    fn callable_item_signature<'db>(
186        &'db self,
187        def: CallableDefId,
188    ) -> EarlyBinder<'db, PolyFnSig<'db>>;
189
190    #[salsa::invoke(crate::lower::trait_environment_for_body_query)]
191    #[salsa::transparent]
192    fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>;
193
194    #[salsa::invoke(crate::lower::trait_environment_query)]
195    fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>;
196
197    #[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)]
198    #[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)]
199    fn generic_defaults_with_diagnostics<'db>(
200        &'db self,
201        def: GenericDefId,
202    ) -> (GenericDefaults<'db>, Diagnostics);
203
204    /// This returns an empty list if no parameter has default.
205    ///
206    /// The binders of the returned defaults are only up to (not including) this parameter.
207    #[salsa::invoke(crate::lower::generic_defaults_query)]
208    #[salsa::transparent]
209    fn generic_defaults<'db>(&'db self, def: GenericDefId) -> GenericDefaults<'db>;
210
211    // Interned IDs for solver integration
212    #[salsa::interned]
213    fn intern_impl_trait_id(&self, id: ImplTraitId<'_>) -> InternedOpaqueTyId;
214
215    #[salsa::interned]
216    fn intern_closure(&self, id: InternedClosure) -> InternedClosureId;
217
218    #[salsa::interned]
219    fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId;
220
221    #[salsa::invoke(crate::variance::variances_of)]
222    #[salsa::cycle(
223        // cycle_fn = crate::variance::variances_of_cycle_fn,
224        // cycle_initial = crate::variance::variances_of_cycle_initial,
225        cycle_result = crate::variance::variances_of_cycle_initial,
226    )]
227    fn variances_of<'db>(&'db self, def: GenericDefId) -> VariancesOf<'db>;
228}
229
230#[test]
231fn hir_database_is_dyn_compatible() {
232    fn _assert_dyn_compatible(_: &dyn HirDatabase) {}
233}
234
235#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
236#[derive(PartialOrd, Ord)]
237pub struct InternedLifetimeParamId {
238    /// This stores the param and its index.
239    pub loc: (LifetimeParamId, u32),
240}
241
242#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
243#[derive(PartialOrd, Ord)]
244pub struct InternedConstParamId {
245    pub loc: ConstParamId,
246}
247
248#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
249#[derive(PartialOrd, Ord)]
250pub struct InternedOpaqueTyId {
251    pub loc: ImplTraitId<'db>,
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
255pub struct InternedClosure(pub DefWithBodyId, pub ExprId);
256
257#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
258#[derive(PartialOrd, Ord)]
259pub struct InternedClosureId {
260    pub loc: InternedClosure,
261}
262
263#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
264pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId);
265
266#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
267#[derive(PartialOrd, Ord)]
268pub struct InternedCoroutineId {
269    pub loc: InternedCoroutine,
270}