Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver.rs')
-rw-r--r--crates/hir-ty/src/next_solver.rs232
1 files changed, 232 insertions, 0 deletions
diff --git a/crates/hir-ty/src/next_solver.rs b/crates/hir-ty/src/next_solver.rs
index 8c52a847d1..605e31404c 100644
--- a/crates/hir-ty/src/next_solver.rs
+++ b/crates/hir-ty/src/next_solver.rs
@@ -1,9 +1,15 @@
//! Things relevant to the next trait solver.
+// Note: in interned types defined in this module, we generally treat the lifetime as advisory
+// and transmute it as needed. This is because no real memory unsafety can be caused from an
+// incorrect lifetime here.
+
pub mod abi;
+mod binder;
mod consts;
mod def_id;
pub mod fold;
+pub mod format_proof_tree;
pub mod fulfill;
mod generic_arg;
pub mod generics;
@@ -21,6 +27,9 @@ mod structural_normalize;
mod ty;
pub mod util;
+use std::{mem::ManuallyDrop, sync::OnceLock};
+
+pub use binder::*;
pub use consts::*;
pub use def_id::*;
pub use generic_arg::*;
@@ -31,6 +40,7 @@ pub use region::*;
pub use solver::*;
pub use ty::*;
+use crate::db::HirDatabase;
pub use crate::lower::ImplTraitIdx;
pub use rustc_ast_ir::Mutability;
@@ -47,3 +57,225 @@ pub type TypingMode<'db> = rustc_type_ir::TypingMode<DbInterner<'db>>;
pub type TypeError<'db> = rustc_type_ir::error::TypeError<DbInterner<'db>>;
pub type QueryResult<'db> = rustc_type_ir::solve::QueryResult<DbInterner<'db>>;
pub type FxIndexMap<K, V> = rustc_type_ir::data_structures::IndexMap<K, V>;
+
+pub struct DefaultTypes<'db> {
+ pub usize: Ty<'db>,
+ pub u8: Ty<'db>,
+ pub u16: Ty<'db>,
+ pub u32: Ty<'db>,
+ pub u64: Ty<'db>,
+ pub u128: Ty<'db>,
+ pub isize: Ty<'db>,
+ pub i8: Ty<'db>,
+ pub i16: Ty<'db>,
+ pub i32: Ty<'db>,
+ pub i64: Ty<'db>,
+ pub i128: Ty<'db>,
+ pub f16: Ty<'db>,
+ pub f32: Ty<'db>,
+ pub f64: Ty<'db>,
+ pub f128: Ty<'db>,
+ pub unit: Ty<'db>,
+ pub bool: Ty<'db>,
+ pub char: Ty<'db>,
+ pub str: Ty<'db>,
+ pub never: Ty<'db>,
+ pub error: Ty<'db>,
+ /// `&'static str`
+ pub static_str_ref: Ty<'db>,
+ /// `*mut ()`
+ pub mut_unit_ptr: Ty<'db>,
+}
+
+pub struct DefaultConsts<'db> {
+ pub error: Const<'db>,
+}
+
+pub struct DefaultRegions<'db> {
+ pub error: Region<'db>,
+ pub statik: Region<'db>,
+ pub erased: Region<'db>,
+}
+
+pub struct DefaultEmpty<'db> {
+ pub tys: Tys<'db>,
+ pub generic_args: GenericArgs<'db>,
+ pub bound_var_kinds: BoundVarKinds<'db>,
+ pub canonical_vars: CanonicalVars<'db>,
+ pub variances: VariancesOf<'db>,
+ pub pat_list: PatList<'db>,
+ pub predefined_opaques: PredefinedOpaques<'db>,
+ pub def_ids: SolverDefIds<'db>,
+ pub bound_existential_predicates: BoundExistentialPredicates<'db>,
+ pub clauses: Clauses<'db>,
+ pub region_assumptions: RegionAssumptions<'db>,
+}
+
+pub struct DefaultAny<'db> {
+ pub types: DefaultTypes<'db>,
+ pub consts: DefaultConsts<'db>,
+ pub regions: DefaultRegions<'db>,
+ pub empty: DefaultEmpty<'db>,
+ /// `[Invariant]`
+ pub one_invariant: VariancesOf<'db>,
+ /// `[Covariant]`
+ pub one_covariant: VariancesOf<'db>,
+ /// `for<'env>`
+ pub coroutine_captures_by_ref_bound_var_kinds: BoundVarKinds<'db>,
+}
+
+impl std::fmt::Debug for DefaultAny<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("DefaultAny").finish_non_exhaustive()
+ }
+}
+
+#[inline]
+pub fn default_types<'a, 'db>(db: &'db dyn HirDatabase) -> &'a DefaultAny<'db> {
+ static TYPES: OnceLock<DefaultAny<'static>> = OnceLock::new();
+
+ let interner = DbInterner::new_no_crate(db);
+ TYPES.get_or_init(|| {
+ let create_ty = |kind| {
+ let ty = Ty::new(interner, kind);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_const = |kind| {
+ let ty = Const::new(interner, kind);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_region = |kind| {
+ let ty = Region::new(interner, kind);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_generic_args = |slice| {
+ let ty = GenericArgs::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_bound_var_kinds = |slice| {
+ let ty = BoundVarKinds::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_canonical_vars = |slice| {
+ let ty = CanonicalVars::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_variances_of = |slice| {
+ let ty = VariancesOf::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_pat_list = |slice| {
+ let ty = PatList::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_predefined_opaques = |slice| {
+ let ty = PredefinedOpaques::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_solver_def_ids = |slice| {
+ let ty = SolverDefIds::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_bound_existential_predicates = |slice| {
+ let ty = BoundExistentialPredicates::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_clauses = |slice| {
+ let ty = Clauses::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_region_assumptions = |slice| {
+ let ty = RegionAssumptions::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+ let create_tys = |slice| {
+ let ty = Tys::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
+
+ let str = create_ty(TyKind::Str);
+ let statik = create_region(RegionKind::ReStatic);
+ let empty_tys = create_tys(&[]);
+ let unit = create_ty(TyKind::Tuple(empty_tys));
+ DefaultAny {
+ types: DefaultTypes {
+ usize: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::Usize)),
+ u8: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U8)),
+ u16: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U16)),
+ u32: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U32)),
+ u64: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U64)),
+ u128: create_ty(TyKind::Uint(rustc_ast_ir::UintTy::U128)),
+ isize: create_ty(TyKind::Int(rustc_ast_ir::IntTy::Isize)),
+ i8: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I8)),
+ i16: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I16)),
+ i32: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I32)),
+ i64: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I64)),
+ i128: create_ty(TyKind::Int(rustc_ast_ir::IntTy::I128)),
+ f16: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F16)),
+ f32: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F32)),
+ f64: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F64)),
+ f128: create_ty(TyKind::Float(rustc_ast_ir::FloatTy::F128)),
+ unit,
+ bool: create_ty(TyKind::Bool),
+ char: create_ty(TyKind::Char),
+ str,
+ never: create_ty(TyKind::Never),
+ error: create_ty(TyKind::Error(ErrorGuaranteed)),
+ static_str_ref: create_ty(TyKind::Ref(statik, str, rustc_ast_ir::Mutability::Not)),
+ mut_unit_ptr: create_ty(TyKind::RawPtr(unit, rustc_ast_ir::Mutability::Mut)),
+ },
+ consts: DefaultConsts { error: create_const(ConstKind::Error(ErrorGuaranteed)) },
+ regions: DefaultRegions {
+ error: create_region(RegionKind::ReError(ErrorGuaranteed)),
+ statik,
+ erased: create_region(RegionKind::ReErased),
+ },
+ empty: DefaultEmpty {
+ tys: empty_tys,
+ generic_args: create_generic_args(&[]),
+ bound_var_kinds: create_bound_var_kinds(&[]),
+ canonical_vars: create_canonical_vars(&[]),
+ variances: create_variances_of(&[]),
+ pat_list: create_pat_list(&[]),
+ predefined_opaques: create_predefined_opaques(&[]),
+ def_ids: create_solver_def_ids(&[]),
+ bound_existential_predicates: create_bound_existential_predicates(&[]),
+ clauses: create_clauses(&[]),
+ region_assumptions: create_region_assumptions(&[]),
+ },
+ one_invariant: create_variances_of(&[rustc_type_ir::Variance::Invariant]),
+ one_covariant: create_variances_of(&[rustc_type_ir::Variance::Covariant]),
+ coroutine_captures_by_ref_bound_var_kinds: create_bound_var_kinds(&[
+ BoundVarKind::Region(BoundRegionKind::ClosureEnv),
+ ]),
+ }
+ })
+}