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.rs | 232 |
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), + ]), + } + }) +} |