Skip to main content

hir_ty/
next_solver.rs

1//! Things relevant to the next trait solver.
2
3// Note: in interned types defined in this module, we generally treat the lifetime as advisory
4// and transmute it as needed. This is because no real memory unsafety can be caused from an
5// incorrect lifetime here.
6
7pub mod abi;
8mod allocation;
9mod binder;
10mod consts;
11mod def_id;
12pub mod fold;
13pub mod format_proof_tree;
14pub mod fulfill;
15mod generic_arg;
16pub mod generics;
17pub mod infer;
18pub(crate) mod inspect;
19pub mod interner;
20mod ir_print;
21pub mod normalize;
22pub mod obligation_ctxt;
23mod opaques;
24pub mod predicate;
25mod region;
26mod solver;
27mod structural_normalize;
28mod ty;
29pub mod util;
30
31use std::{mem::ManuallyDrop, sync::OnceLock};
32
33pub use allocation::*;
34pub use binder::*;
35pub use consts::*;
36pub use def_id::*;
37pub use generic_arg::*;
38pub use interner::*;
39pub use opaques::*;
40pub use predicate::*;
41pub use region::*;
42use rustc_type_ir::MayBeErased;
43pub use solver::*;
44pub use ty::*;
45
46use crate::db::HirDatabase;
47pub use crate::lower::ImplTraitIdx;
48pub use rustc_ast_ir::Mutability;
49
50pub type Binder<'db, T> = rustc_type_ir::Binder<DbInterner<'db>, T>;
51pub type EarlyBinder<'db, T> = rustc_type_ir::EarlyBinder<DbInterner<'db>, T>;
52pub type Unnormalized<'db, T> = rustc_type_ir::Unnormalized<DbInterner<'db>, T>;
53pub type Canonical<'db, T> = rustc_type_ir::Canonical<DbInterner<'db>, T>;
54pub type CanonicalVarValues<'db> = rustc_type_ir::CanonicalVarValues<DbInterner<'db>>;
55pub type CanonicalVarKind<'db> = rustc_type_ir::CanonicalVarKind<DbInterner<'db>>;
56pub type CanonicalQueryInput<'db, V> = rustc_type_ir::CanonicalQueryInput<DbInterner<'db>, V>;
57pub type AliasTy<'db> = rustc_type_ir::AliasTy<DbInterner<'db>>;
58pub type FnSig<'db> = rustc_type_ir::FnSig<DbInterner<'db>>;
59pub type PolyFnSig<'db> = Binder<'db, rustc_type_ir::FnSig<DbInterner<'db>>>;
60pub type TypingMode<'db, S = MayBeErased> = rustc_type_ir::TypingMode<DbInterner<'db>, S>;
61pub type TypeError<'db> = rustc_type_ir::error::TypeError<DbInterner<'db>>;
62pub type QueryResult<'db> = rustc_type_ir::solve::QueryResult<DbInterner<'db>>;
63pub type FxIndexMap<K, V> = rustc_type_ir::data_structures::IndexMap<K, V>;
64
65pub struct DefaultTypes<'db> {
66    pub usize: Ty<'db>,
67    pub u8: Ty<'db>,
68    pub u16: Ty<'db>,
69    pub u32: Ty<'db>,
70    pub u64: Ty<'db>,
71    pub u128: Ty<'db>,
72    pub isize: Ty<'db>,
73    pub i8: Ty<'db>,
74    pub i16: Ty<'db>,
75    pub i32: Ty<'db>,
76    pub i64: Ty<'db>,
77    pub i128: Ty<'db>,
78    pub f16: Ty<'db>,
79    pub f32: Ty<'db>,
80    pub f64: Ty<'db>,
81    pub f128: Ty<'db>,
82    pub unit: Ty<'db>,
83    pub bool: Ty<'db>,
84    pub char: Ty<'db>,
85    pub str: Ty<'db>,
86    pub never: Ty<'db>,
87    pub error: Ty<'db>,
88    /// `&'static str`
89    pub static_str_ref: Ty<'db>,
90    /// `[u8]`
91    pub u8_slice: Ty<'db>,
92    /// `&'static [u8]`
93    pub static_u8_slice: Ty<'db>,
94    /// `*mut ()`
95    pub mut_unit_ptr: Ty<'db>,
96    pub dyn_trait_dummy_self: Ty<'db>,
97}
98
99pub struct DefaultConsts<'db> {
100    pub error: Const<'db>,
101    pub u8_values: [Const<'db>; 256],
102}
103
104pub struct DefaultRegions<'db> {
105    pub error: Region<'db>,
106    pub statik: Region<'db>,
107    pub erased: Region<'db>,
108}
109
110pub struct DefaultEmpty<'db> {
111    pub tys: Tys<'db>,
112    pub generic_args: GenericArgs<'db>,
113    pub bound_var_kinds: BoundVarKinds<'db>,
114    pub canonical_vars: CanonicalVarKinds<'db>,
115    pub variances: VariancesOf<'db>,
116    pub pat_list: PatList<'db>,
117    pub predefined_opaques: PredefinedOpaques<'db>,
118    pub def_ids: SolverDefIds<'db>,
119    pub bound_existential_predicates: BoundExistentialPredicates<'db>,
120    pub clauses: Clauses<'db>,
121    pub region_assumptions: RegionAssumptions<'db>,
122    pub consts: Consts<'db>,
123    pub projection: crate::mir::Projection<'db>,
124}
125
126pub struct DefaultAny<'db> {
127    pub types: DefaultTypes<'db>,
128    pub consts: DefaultConsts<'db>,
129    pub regions: DefaultRegions<'db>,
130    pub empty: DefaultEmpty<'db>,
131    /// `[Invariant]`
132    pub one_invariant: VariancesOf<'db>,
133    /// `[Covariant]`
134    pub one_covariant: VariancesOf<'db>,
135    /// `for<'env>`
136    pub coroutine_captures_by_ref_bound_var_kinds: BoundVarKinds<'db>,
137}
138
139impl std::fmt::Debug for DefaultAny<'_> {
140    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141        f.debug_struct("DefaultAny").finish_non_exhaustive()
142    }
143}
144
145#[inline]
146pub fn default_types<'db>(db: &'db dyn HirDatabase) -> &'db DefaultAny<'db> {
147    static TYPES: OnceLock<DefaultAny<'static>> = OnceLock::new();
148
149    let interner = DbInterner::new_no_crate(db);
150    TYPES.get_or_init(|| {
151        let create_ty = |kind| {
152            let ty = Ty::new(interner, kind);
153            // We need to increase the refcount (forever), so that the types won't be freed.
154            let ty = ManuallyDrop::new(ty.store());
155            ty.as_ref()
156        };
157        let create_const = |kind| {
158            let ty = Const::new(interner, kind);
159            // We need to increase the refcount (forever), so that the types won't be freed.
160            let ty = ManuallyDrop::new(ty.store());
161            ty.as_ref()
162        };
163        let create_region = |kind| {
164            let ty = Region::new(interner, kind);
165            // We need to increase the refcount (forever), so that the types won't be freed.
166            let ty = ManuallyDrop::new(ty.store());
167            ty.as_ref()
168        };
169        let create_generic_args = |slice| {
170            let ty = GenericArgs::new_from_slice(slice);
171            // We need to increase the refcount (forever), so that the types won't be freed.
172            let ty = ManuallyDrop::new(ty.store());
173            ty.as_ref()
174        };
175        let create_bound_var_kinds = |slice| {
176            let ty = BoundVarKinds::new_from_slice(slice);
177            // We need to increase the refcount (forever), so that the types won't be freed.
178            let ty = ManuallyDrop::new(ty.store());
179            ty.as_ref()
180        };
181        let create_canonical_vars = |slice| {
182            let ty = CanonicalVarKinds::new_from_slice(slice);
183            // We need to increase the refcount (forever), so that the types won't be freed.
184            let ty = ManuallyDrop::new(ty.store());
185            ty.as_ref()
186        };
187        let create_variances_of = |slice| {
188            let ty = VariancesOf::new_from_slice(slice);
189            // We need to increase the refcount (forever), so that the types won't be freed.
190            let ty = ManuallyDrop::new(ty.store());
191            ty.as_ref()
192        };
193        let create_pat_list = |slice| {
194            let ty = PatList::new_from_slice(slice);
195            // We need to increase the refcount (forever), so that the types won't be freed.
196            let ty = ManuallyDrop::new(ty.store());
197            ty.as_ref()
198        };
199        let create_predefined_opaques = |slice| {
200            let ty = PredefinedOpaques::new_from_slice(slice);
201            // We need to increase the refcount (forever), so that the types won't be freed.
202            let ty = ManuallyDrop::new(ty.store());
203            ty.as_ref()
204        };
205        let create_solver_def_ids = |slice| {
206            let ty = SolverDefIds::new_from_slice(slice);
207            // We need to increase the refcount (forever), so that the types won't be freed.
208            let ty = ManuallyDrop::new(ty.store());
209            ty.as_ref()
210        };
211        let create_bound_existential_predicates = |slice| {
212            let ty = BoundExistentialPredicates::new_from_slice(slice);
213            // We need to increase the refcount (forever), so that the types won't be freed.
214            let ty = ManuallyDrop::new(ty.store());
215            ty.as_ref()
216        };
217        let create_clauses = |slice| {
218            let ty = Clauses::new_from_slice(slice);
219            // We need to increase the refcount (forever), so that the types won't be freed.
220            let ty = ManuallyDrop::new(ty.store());
221            ty.as_ref()
222        };
223        let create_region_assumptions = |slice| {
224            let ty = RegionAssumptions::new_from_slice(slice);
225            // We need to increase the refcount (forever), so that the types won't be freed.
226            let ty = ManuallyDrop::new(ty.store());
227            ty.as_ref()
228        };
229        let create_tys = |slice| {
230            let ty = Tys::new_from_slice(slice);
231            // We need to increase the refcount (forever), so that the types won't be freed.
232            let ty = ManuallyDrop::new(ty.store());
233            ty.as_ref()
234        };
235        let create_consts = |slice| {
236            let ty = Consts::new_from_slice(slice);
237            // We need to increase the refcount (forever), so that the types won't be freed.
238            let ty = ManuallyDrop::new(ty.store());
239            ty.as_ref()
240        };
241        let create_projection = |slice| {
242            let it = crate::mir::Projection::new_from_slice(slice);
243            // We need to increase the refcount (forever), so that the types won't be freed.
244            let it = ManuallyDrop::new(it.store());
245            it.as_ref()
246        };
247
248        let str = create_ty(TyKind::Str);
249        let statik = create_region(RegionKind::ReStatic);
250        let empty_tys = create_tys(&[]);
251        let unit = create_ty(TyKind::Tuple(empty_tys));
252        let u8 = create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U8));
253        let u8_slice = create_ty(TyKind::Slice(u8));
254        let static_u8_slice = create_ty(TyKind::Ref(statik, u8_slice, Mutability::Not));
255        DefaultAny {
256            types: DefaultTypes {
257                usize: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::Usize)),
258                u8,
259                u16: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U16)),
260                u32: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U32)),
261                u64: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U64)),
262                u128: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U128)),
263                isize: create_ty(TyKind::Int(rustc_ast_ir::IntTy::Isize)),
264                i8: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I8)),
265                i16: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I16)),
266                i32: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I32)),
267                i64: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I64)),
268                i128: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I128)),
269                f16: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F16)),
270                f32: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F32)),
271                f64: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F64)),
272                f128: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F128)),
273                unit,
274                bool: create_ty(TyKind::Bool),
275                char: create_ty(TyKind::Char),
276                str,
277                never: create_ty(TyKind::Never),
278                error: create_ty(TyKind::Error(ErrorGuaranteed)),
279                static_str_ref: create_ty(TyKind::Ref(statik, str, rustc_ast_ir::Mutability::Not)),
280                u8_slice,
281                static_u8_slice,
282                mut_unit_ptr: create_ty(TyKind::RawPtr(unit, rustc_ast_ir::Mutability::Mut)),
283                // This type must not appear anywhere except here.
284                dyn_trait_dummy_self: create_ty(TyKind::Infer(rustc_type_ir::InferTy::FreshTy(0))),
285            },
286            consts: DefaultConsts {
287                error: create_const(ConstKind::Error(ErrorGuaranteed)),
288                u8_values: std::array::from_fn(|u8_value| {
289                    create_const(ConstKind::Value(ValueConst {
290                        ty: u8,
291                        value: ValTree::new(ValTreeKind::Leaf(ScalarInt::from(u8_value as u8))),
292                    }))
293                }),
294            },
295            regions: DefaultRegions {
296                error: create_region(RegionKind::ReError(ErrorGuaranteed)),
297                statik,
298                erased: create_region(RegionKind::ReErased),
299            },
300            empty: DefaultEmpty {
301                tys: empty_tys,
302                generic_args: create_generic_args(&[]),
303                bound_var_kinds: create_bound_var_kinds(&[]),
304                canonical_vars: create_canonical_vars(&[]),
305                variances: create_variances_of(&[]),
306                pat_list: create_pat_list(&[]),
307                predefined_opaques: create_predefined_opaques(&[]),
308                def_ids: create_solver_def_ids(&[]),
309                bound_existential_predicates: create_bound_existential_predicates(&[]),
310                clauses: create_clauses(&[]),
311                region_assumptions: create_region_assumptions(&[]),
312                consts: create_consts(&[]),
313                projection: create_projection(&[]),
314            },
315            one_invariant: create_variances_of(&[rustc_type_ir::Variance::Invariant]),
316            one_covariant: create_variances_of(&[rustc_type_ir::Variance::Covariant]),
317            coroutine_captures_by_ref_bound_var_kinds: create_bound_var_kinds(&[
318                BoundVariableKind::Region(BoundRegionKind::ClosureEnv),
319            ]),
320        }
321    })
322}