From 096ebb0759a8fb1823dfc4200d2cd6b8ecaeaf26 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 18 Dec 2025 03:18:39 +0200 Subject: [PATCH] Pre-intern some common types This is possible now that they are no longer interned with Salsa. --- crates/hir-ty/src/infer.rs | 113 ++-------- crates/hir-ty/src/infer/closure.rs | 27 ++- crates/hir-ty/src/infer/closure/analysis.rs | 2 +- crates/hir-ty/src/infer/coerce.rs | 6 +- crates/hir-ty/src/infer/expr.rs | 135 ++++++----- crates/hir-ty/src/infer/fallback.rs | 14 +- crates/hir-ty/src/infer/op.rs | 20 +- crates/hir-ty/src/infer/opaques.rs | 7 +- crates/hir-ty/src/infer/pat.rs | 14 +- crates/hir-ty/src/infer/path.rs | 2 +- crates/hir-ty/src/infer/place_op.rs | 2 +- crates/hir-ty/src/lower.rs | 4 +- crates/hir-ty/src/mir/lower.rs | 8 +- crates/hir-ty/src/next_solver.rs | 225 +++++++++++++++++++ crates/hir-ty/src/next_solver/consts.rs | 6 +- crates/hir-ty/src/next_solver/generic_arg.rs | 12 +- crates/hir-ty/src/next_solver/interner.rs | 93 ++++---- crates/hir-ty/src/next_solver/opaques.rs | 11 +- crates/hir-ty/src/next_solver/predicate.rs | 2 + crates/hir-ty/src/next_solver/region.rs | 14 +- crates/hir-ty/src/next_solver/ty.rs | 117 ++++++---- crates/hir-ty/src/next_solver/util.rs | 45 ++-- crates/hir-ty/src/variance.rs | 5 +- 23 files changed, 558 insertions(+), 326 deletions(-) diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index bd5fffc4cc..4f739dc8ee 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -51,7 +51,7 @@ use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ AliasTyKind, TypeFoldable, - inherent::{AdtDef, IntoKind, Region as _, Ty as _}, + inherent::{AdtDef, IntoKind, Ty as _}, }; use span::Edition; use stdx::never; @@ -108,23 +108,23 @@ fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult { DefWithBodyId::VariantId(v) => { ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) { hir_def::layout::IntegerType::Pointer(signed) => match signed { - true => ctx.types.isize, - false => ctx.types.usize, + true => ctx.types.types.isize, + false => ctx.types.types.usize, }, hir_def::layout::IntegerType::Fixed(size, signed) => match signed { true => match size { - Integer::I8 => ctx.types.i8, - Integer::I16 => ctx.types.i16, - Integer::I32 => ctx.types.i32, - Integer::I64 => ctx.types.i64, - Integer::I128 => ctx.types.i128, + Integer::I8 => ctx.types.types.i8, + Integer::I16 => ctx.types.types.i16, + Integer::I32 => ctx.types.types.i32, + Integer::I64 => ctx.types.types.i64, + Integer::I128 => ctx.types.types.i128, }, false => match size { - Integer::I8 => ctx.types.u8, - Integer::I16 => ctx.types.u16, - Integer::I32 => ctx.types.u32, - Integer::I64 => ctx.types.u64, - Integer::I128 => ctx.types.u128, + Integer::I8 => ctx.types.types.u8, + Integer::I16 => ctx.types.types.u16, + Integer::I32 => ctx.types.types.u32, + Integer::I64 => ctx.types.types.u64, + Integer::I128 => ctx.types.types.u128, }, }, }; @@ -738,75 +738,6 @@ impl InferenceResult { } } -#[derive(Debug, Clone)] -struct InternedStandardTypes<'db> { - unit: Ty<'db>, - never: Ty<'db>, - char: Ty<'db>, - bool: Ty<'db>, - i8: Ty<'db>, - i16: Ty<'db>, - i32: Ty<'db>, - i64: Ty<'db>, - i128: Ty<'db>, - isize: Ty<'db>, - u8: Ty<'db>, - u16: Ty<'db>, - u32: Ty<'db>, - u64: Ty<'db>, - u128: Ty<'db>, - usize: Ty<'db>, - f16: Ty<'db>, - f32: Ty<'db>, - f64: Ty<'db>, - f128: Ty<'db>, - static_str_ref: Ty<'db>, - error: Ty<'db>, - - re_static: Region<'db>, - re_error: Region<'db>, - re_erased: Region<'db>, - - empty_args: GenericArgs<'db>, -} - -impl<'db> InternedStandardTypes<'db> { - fn new(interner: DbInterner<'db>) -> Self { - let str = Ty::new(interner, rustc_type_ir::TyKind::Str); - let re_static = Region::new_static(interner); - Self { - unit: Ty::new_unit(interner), - never: Ty::new(interner, TyKind::Never), - char: Ty::new(interner, TyKind::Char), - bool: Ty::new(interner, TyKind::Bool), - i8: Ty::new_int(interner, rustc_type_ir::IntTy::I8), - i16: Ty::new_int(interner, rustc_type_ir::IntTy::I16), - i32: Ty::new_int(interner, rustc_type_ir::IntTy::I32), - i64: Ty::new_int(interner, rustc_type_ir::IntTy::I64), - i128: Ty::new_int(interner, rustc_type_ir::IntTy::I128), - isize: Ty::new_int(interner, rustc_type_ir::IntTy::Isize), - u8: Ty::new_uint(interner, rustc_type_ir::UintTy::U8), - u16: Ty::new_uint(interner, rustc_type_ir::UintTy::U16), - u32: Ty::new_uint(interner, rustc_type_ir::UintTy::U32), - u64: Ty::new_uint(interner, rustc_type_ir::UintTy::U64), - u128: Ty::new_uint(interner, rustc_type_ir::UintTy::U128), - usize: Ty::new_uint(interner, rustc_type_ir::UintTy::Usize), - f16: Ty::new_float(interner, rustc_type_ir::FloatTy::F16), - f32: Ty::new_float(interner, rustc_type_ir::FloatTy::F32), - f64: Ty::new_float(interner, rustc_type_ir::FloatTy::F64), - f128: Ty::new_float(interner, rustc_type_ir::FloatTy::F128), - static_str_ref: Ty::new_ref(interner, re_static, str, Mutability::Not), - error: Ty::new_error(interner, ErrorGuaranteed), - - re_static, - re_error: Region::error(interner), - re_erased: Region::new_erased(interner), - - empty_args: GenericArgs::empty(interner), - } - } -} - /// The inference context contains all information needed during type inference. #[derive(Clone, Debug)] pub(crate) struct InferenceContext<'body, 'db> { @@ -841,7 +772,7 @@ pub(crate) struct InferenceContext<'body, 'db> { resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>, diverges: Diverges, breakables: Vec>, - types: InternedStandardTypes<'db>, + types: &'db crate::next_solver::DefaultAny<'db>, /// Whether we are inside the pattern of a destructuring assignment. inside_assignment: bool, @@ -918,10 +849,10 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ) -> Self { let trait_env = db.trait_environment_for_body(owner); let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner)); - let types = InternedStandardTypes::new(table.interner()); + let types = crate::next_solver::default_types(db); InferenceContext { - result: InferenceResult::new(types.error), - return_ty: types.error, // set in collect_* calls + result: InferenceResult::new(types.types.error), + return_ty: types.types.error, // set in collect_* calls types, target_features: OnceCell::new(), unstable_features: MethodResolutionUnstableFeatures::from_def_map( @@ -1153,7 +1084,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature, - LifetimeElisionKind::Elided(self.types.re_static), + LifetimeElisionKind::Elided(self.types.regions.statik), ); self.return_ty = return_ty; @@ -1211,7 +1142,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ); self.process_user_written_ty(return_ty) } - None => self.types.unit, + None => self.types.types.unit, }; self.return_coercion = Some(CoerceMany::new(self.return_ty)); @@ -1408,7 +1339,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn err_ty(&self) -> Ty<'db> { - self.types.error + self.types.types.error } pub(crate) fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> { @@ -1573,7 +1504,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { if let Err(_err) = result { // FIXME: Emit diagnostic. } - result.unwrap_or(self.types.error) + result.unwrap_or(self.types.types.error) } fn expr_ty(&self, expr: ExprId) -> Ty<'db> { @@ -1805,7 +1736,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { result } else { // FIXME diagnostic - (ctx.types.error, None) + (ctx.types.types.error, None) } } } diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 82912017c3..19ffa3a939 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -22,9 +22,8 @@ use crate::{ db::{InternedClosure, InternedCoroutine}, infer::{BreakableKind, Diverges, coerce::CoerceMany}, next_solver::{ - AliasTy, Binder, BoundRegionKind, BoundVarKind, BoundVarKinds, ClauseKind, DbInterner, - ErrorGuaranteed, FnSig, GenericArgs, PolyFnSig, PolyProjectionPredicate, Predicate, - PredicateKind, SolverDefId, Ty, TyKind, + AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArgs, PolyFnSig, + PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, Ty, TyKind, abi::Safety, infer::{ BoundRegionConversionTime, InferOk, InferResult, @@ -73,16 +72,17 @@ impl<'db> InferenceContext<'_, 'db> { let parent_args = GenericArgs::identity_for_item(interner, self.generic_def.into()); // FIXME: Make this an infer var and infer it later. - let tupled_upvars_ty = self.types.unit; + let tupled_upvars_ty = self.types.types.unit; let (id, ty, resume_yield_tys) = match closure_kind { ClosureKind::Coroutine(_) => { let yield_ty = self.table.next_ty_var(); - let resume_ty = liberated_sig.inputs().first().copied().unwrap_or(self.types.unit); + let resume_ty = + liberated_sig.inputs().first().copied().unwrap_or(self.types.types.unit); // FIXME: Infer the upvars later. let parts = CoroutineArgsParts { parent_args: parent_args.as_slice(), - kind_ty: self.types.unit, + kind_ty: self.types.types.unit, resume_ty, yield_ty, return_ty: body_ret_ty, @@ -140,9 +140,9 @@ impl<'db> InferenceContext<'_, 'db> { // async closures always return the type ascribed after the `->` (if present), // and yield `()`. let bound_return_ty = bound_sig.skip_binder().output(); - let bound_yield_ty = self.types.unit; + let bound_yield_ty = self.types.types.unit; // rustc uses a special lang item type for the resume ty. I don't believe this can cause us problems. - let resume_ty = self.types.unit; + let resume_ty = self.types.types.unit; // FIXME: Infer the kind later if needed. let closure_kind_ty = Ty::from_closure_kind( @@ -155,11 +155,14 @@ impl<'db> InferenceContext<'_, 'db> { let coroutine_captures_by_ref_ty = Ty::new_fn_ptr( interner, Binder::bind_with_vars( - interner.mk_fn_sig([], self.types.unit, false, Safety::Safe, FnAbi::Rust), - BoundVarKinds::new_from_iter( - interner, - [BoundVarKind::Region(BoundRegionKind::ClosureEnv)], + interner.mk_fn_sig( + [], + self.types.types.unit, + false, + Safety::Safe, + FnAbi::Rust, ), + self.types.coroutine_captures_by_ref_bound_var_kinds, ), ); let closure_args = CoroutineClosureArgs::new( diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index a7369d606d..5b0360071d 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -289,7 +289,7 @@ impl CapturedItemWithoutTy { BorrowKind::Mut { .. } => Mutability::Mut, _ => Mutability::Not, }; - Ty::new_ref(ctx.interner(), ctx.types.re_error, ty, m) + Ty::new_ref(ctx.interner(), ctx.types.regions.error, ty, m) } }; CapturedItem { diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs index 1233543c40..bb9cb1c1ca 100644 --- a/crates/hir-ty/src/infer/coerce.rs +++ b/crates/hir-ty/src/infer/coerce.rs @@ -1397,7 +1397,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { icx, cause, expr, - icx.types.unit, + icx.types.types.unit, true, label_unit_as_expected, expr_is_read, @@ -1512,7 +1512,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { // emit or provide suggestions on how to fix the initial error. icx.set_tainted_by_errors(); - self.final_ty = Some(icx.types.error); + self.final_ty = Some(icx.types.types.error); icx.result.type_mismatches.get_or_insert_default().insert( expression.into(), @@ -1535,7 +1535,7 @@ impl<'db, 'exprs> CoerceMany<'db, 'exprs> { // If we only had inputs that were of type `!` (or no // inputs at all), then the final type is `!`. assert_eq!(self.pushed, 0); - icx.types.never + icx.types.types.never } } } diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 4d3ca94b22..ae69e5176a 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -319,7 +319,7 @@ impl<'db> InferenceContext<'_, 'db> { let expected = &expected.adjust_for_branches(&mut self.table); self.infer_expr_coerce_never( condition, - &Expectation::HasType(self.types.bool), + &Expectation::HasType(self.types.types.bool), ExprIsRead::Yes, ); @@ -375,7 +375,7 @@ impl<'db> InferenceContext<'_, 'db> { input_ty, Some(DeclContext { origin: DeclOrigin::LetExpr }), ); - self.types.bool + self.types.types.bool } Expr::Block { statements, tail, label, id: _ } => { self.infer_block(tgt_expr, statements, *tail, *label, expected) @@ -400,7 +400,7 @@ impl<'db> InferenceContext<'_, 'db> { self.with_breakable_ctx(BreakableKind::Loop, Some(ty), label, |this| { this.infer_expr( body, - &Expectation::HasType(this.types.unit), + &Expectation::HasType(this.types.types.unit), ExprIsRead::Yes, ); }); @@ -410,7 +410,7 @@ impl<'db> InferenceContext<'_, 'db> { self.diverges = Diverges::Maybe; breaks } - None => self.types.never, + None => self.types.types.never, } } Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self @@ -451,7 +451,7 @@ impl<'db> InferenceContext<'_, 'db> { if arms.is_empty() { self.diverges = Diverges::Always; - self.types.never + self.types.types.never } else { let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); let mut all_arms_diverge = Diverges::Always; @@ -463,7 +463,7 @@ impl<'db> InferenceContext<'_, 'db> { let result_ty = match &expected { // We don't coerce to `()` so that if the match expression is a // statement it's branches can have any consistent type. - Expectation::HasType(ty) if *ty != self.types.unit => *ty, + Expectation::HasType(ty) if *ty != self.types.types.unit => *ty, _ => self.table.next_ty_var(), }; let mut coerce = CoerceMany::new(result_ty); @@ -473,7 +473,7 @@ impl<'db> InferenceContext<'_, 'db> { self.diverges = Diverges::Maybe; self.infer_expr_coerce_never( guard_expr, - &Expectation::HasType(self.types.bool), + &Expectation::HasType(self.types.types.bool), ExprIsRead::Yes, ); } @@ -504,7 +504,7 @@ impl<'db> InferenceContext<'_, 'db> { bad_value_break: false, }); }; - self.types.never + self.types.types.never } &Expr::Break { expr, label } => { let val_ty = if let Some(expr) = expr { @@ -528,7 +528,7 @@ impl<'db> InferenceContext<'_, 'db> { ExprIsRead::Yes, ) } else { - self.types.unit + self.types.types.unit }; match find_breakable(&mut self.breakables, label) { @@ -558,7 +558,7 @@ impl<'db> InferenceContext<'_, 'db> { }); } } - self.types.never + self.types.types.never } &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr), &Expr::Become { expr } => self.infer_expr_become(expr), @@ -571,7 +571,7 @@ impl<'db> InferenceContext<'_, 'db> { ExprIsRead::Yes, ); } else { - let unit = self.types.unit; + let unit = self.types.types.unit; let _ = self.coerce( tgt_expr.into(), unit, @@ -583,14 +583,14 @@ impl<'db> InferenceContext<'_, 'db> { resume_ty } else { // FIXME: report error (yield expr in non-coroutine) - self.types.error + self.types.types.error } } Expr::Yeet { expr } => { if let &Some(expr) = expr { self.infer_expr_no_expect(expr, ExprIsRead::Yes); } - self.types.never + self.types.types.never } Expr::RecordLit { path, fields, spread, .. } => { let (ty, def_id) = self.resolve_variant(tgt_expr.into(), path.as_deref(), false); @@ -599,7 +599,7 @@ impl<'db> InferenceContext<'_, 'db> { self.unify(ty, t); } - let substs = ty.as_adt().map(|(_, s)| s).unwrap_or(self.types.empty_args); + let substs = ty.as_adt().map(|(_, s)| s).unwrap_or(self.types.empty.generic_args); if let Some(variant) = def_id { self.write_variant_resolution(tgt_expr.into(), variant); } @@ -768,7 +768,7 @@ impl<'db> InferenceContext<'_, 'db> { // assignments into blocks. self.table.new_maybe_never_var() } else { - self.types.unit + self.types.types.unit } } Expr::Range { lhs, rhs, range_type } => { @@ -785,7 +785,9 @@ impl<'db> InferenceContext<'_, 'db> { }; match (range_type, lhs_ty, rhs_ty) { (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { - Some(adt) => Ty::new_adt(self.interner(), adt, self.types.empty_args), + Some(adt) => { + Ty::new_adt(self.interner(), adt, self.types.empty.generic_args) + } None => self.err_ty(), }, (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { @@ -834,7 +836,7 @@ impl<'db> InferenceContext<'_, 'db> { trait_element_ty } // FIXME: Report an error. - None => self.types.error, + None => self.types.types.error, } } Expr::Tuple { exprs, .. } => { @@ -859,10 +861,10 @@ impl<'db> InferenceContext<'_, 'db> { } Expr::Array(array) => self.infer_expr_array(array, expected), Expr::Literal(lit) => match lit { - Literal::Bool(..) => self.types.bool, - Literal::String(..) => self.types.static_str_ref, + Literal::Bool(..) => self.types.types.bool, + Literal::String(..) => self.types.types.static_str_ref, Literal::ByteString(bs) => { - let byte_type = self.types.u8; + let byte_type = self.types.types.u8; let len = consteval::usize_const( self.db, @@ -871,35 +873,46 @@ impl<'db> InferenceContext<'_, 'db> { ); let array_type = Ty::new_array_with_const_len(self.interner(), byte_type, len); - Ty::new_ref(self.interner(), self.types.re_static, array_type, Mutability::Not) + Ty::new_ref( + self.interner(), + self.types.regions.statik, + array_type, + Mutability::Not, + ) } Literal::CString(..) => Ty::new_ref( self.interner(), - self.types.re_static, + self.types.regions.statik, self.lang_items.CStr.map_or_else( || self.err_ty(), - |strukt| Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args), + |strukt| { + Ty::new_adt( + self.interner(), + strukt.into(), + self.types.empty.generic_args, + ) + }, ), Mutability::Not, ), - Literal::Char(..) => self.types.char, + Literal::Char(..) => self.types.types.char, Literal::Int(_v, ty) => match ty { Some(int_ty) => match int_ty { - hir_def::builtin_type::BuiltinInt::Isize => self.types.isize, - hir_def::builtin_type::BuiltinInt::I8 => self.types.i8, - hir_def::builtin_type::BuiltinInt::I16 => self.types.i16, - hir_def::builtin_type::BuiltinInt::I32 => self.types.i32, - hir_def::builtin_type::BuiltinInt::I64 => self.types.i64, - hir_def::builtin_type::BuiltinInt::I128 => self.types.i128, + hir_def::builtin_type::BuiltinInt::Isize => self.types.types.isize, + hir_def::builtin_type::BuiltinInt::I8 => self.types.types.i8, + hir_def::builtin_type::BuiltinInt::I16 => self.types.types.i16, + hir_def::builtin_type::BuiltinInt::I32 => self.types.types.i32, + hir_def::builtin_type::BuiltinInt::I64 => self.types.types.i64, + hir_def::builtin_type::BuiltinInt::I128 => self.types.types.i128, }, None => { let expected_ty = expected.to_option(&mut self.table); tracing::debug!(?expected_ty); let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, - Some(TyKind::Char) => Some(self.types.u8), + Some(TyKind::Char) => Some(self.types.types.u8), Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { - Some(self.types.usize) + Some(self.types.types.usize) } _ => None, }; @@ -908,20 +921,20 @@ impl<'db> InferenceContext<'_, 'db> { }, Literal::Uint(_v, ty) => match ty { Some(int_ty) => match int_ty { - hir_def::builtin_type::BuiltinUint::Usize => self.types.usize, - hir_def::builtin_type::BuiltinUint::U8 => self.types.u8, - hir_def::builtin_type::BuiltinUint::U16 => self.types.u16, - hir_def::builtin_type::BuiltinUint::U32 => self.types.u32, - hir_def::builtin_type::BuiltinUint::U64 => self.types.u64, - hir_def::builtin_type::BuiltinUint::U128 => self.types.u128, + hir_def::builtin_type::BuiltinUint::Usize => self.types.types.usize, + hir_def::builtin_type::BuiltinUint::U8 => self.types.types.u8, + hir_def::builtin_type::BuiltinUint::U16 => self.types.types.u16, + hir_def::builtin_type::BuiltinUint::U32 => self.types.types.u32, + hir_def::builtin_type::BuiltinUint::U64 => self.types.types.u64, + hir_def::builtin_type::BuiltinUint::U128 => self.types.types.u128, }, None => { let expected_ty = expected.to_option(&mut self.table); let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) { Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty, - Some(TyKind::Char) => Some(self.types.u8), + Some(TyKind::Char) => Some(self.types.types.u8), Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => { - Some(self.types.usize) + Some(self.types.types.usize) } _ => None, }; @@ -930,10 +943,10 @@ impl<'db> InferenceContext<'_, 'db> { }, Literal::Float(_v, ty) => match ty { Some(float_ty) => match float_ty { - hir_def::builtin_type::BuiltinFloat::F16 => self.types.f16, - hir_def::builtin_type::BuiltinFloat::F32 => self.types.f32, - hir_def::builtin_type::BuiltinFloat::F64 => self.types.f64, - hir_def::builtin_type::BuiltinFloat::F128 => self.types.f128, + hir_def::builtin_type::BuiltinFloat::F16 => self.types.types.f16, + hir_def::builtin_type::BuiltinFloat::F32 => self.types.types.f32, + hir_def::builtin_type::BuiltinFloat::F64 => self.types.types.f64, + hir_def::builtin_type::BuiltinFloat::F128 => self.types.types.f128, }, None => { let opt_ty = expected @@ -953,7 +966,7 @@ impl<'db> InferenceContext<'_, 'db> { }); expected } - Expr::OffsetOf(_) => self.types.usize, + Expr::OffsetOf(_) => self.types.types.usize, Expr::InlineAsm(asm) => { let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| { let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes); @@ -1014,7 +1027,7 @@ impl<'db> InferenceContext<'_, 'db> { AsmOperand::Label(expr) => { self.infer_expr( expr, - &Expectation::HasType(self.types.unit), + &Expectation::HasType(self.types.types.unit), ExprIsRead::No, ); } @@ -1024,7 +1037,7 @@ impl<'db> InferenceContext<'_, 'db> { // FIXME: `sym` should report for things that are not functions or statics. AsmOperand::Sym(_) => (), }); - if diverge { self.types.never } else { self.types.unit } + if diverge { self.types.types.never } else { self.types.types.unit } } }; // use a new type variable if we got unknown here @@ -1146,7 +1159,7 @@ impl<'db> InferenceContext<'_, 'db> { oprnd_t = ty; } else { // FIXME: Report an error. - oprnd_t = self.types.error; + oprnd_t = self.types.types.error; } } UnaryOp::Not => { @@ -1220,13 +1233,13 @@ impl<'db> InferenceContext<'_, 'db> { self.interner(), CoroutineArgsParts { parent_args: parent_args.as_slice(), - kind_ty: self.types.unit, + kind_ty: self.types.types.unit, // rustc uses a special lang item type for the resume ty. I don't believe this can cause us problems. - resume_ty: self.types.unit, - yield_ty: self.types.unit, + resume_ty: self.types.types.unit, + yield_ty: self.types.types.unit, return_ty: inner_ty, // FIXME: Infer upvars. - tupled_upvars_ty: self.types.unit, + tupled_upvars_ty: self.types.types.unit, }, ) .args, @@ -1333,7 +1346,7 @@ impl<'db> InferenceContext<'_, 'db> { &Expectation::has_type(elem_ty), ExprIsRead::Yes, ); - let usize = self.types.usize; + let usize = self.types.types.usize; let len = match self.body[repeat] { Expr::Underscore => { self.write_expr_ty(repeat, usize); @@ -1390,7 +1403,7 @@ impl<'db> InferenceContext<'_, 'db> { } } } - self.types.never + self.types.types.never } fn infer_expr_become(&mut self, expr: ExprId) -> Ty<'db> { @@ -1411,7 +1424,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - self.types.never + self.types.types.never } fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation<'db>) -> Ty<'db> { @@ -1502,7 +1515,7 @@ impl<'db> InferenceContext<'_, 'db> { mem::replace(&mut this.diverges, Diverges::Maybe); this.infer_expr_coerce( *expr, - &Expectation::HasType(this.types.never), + &Expectation::HasType(this.types.types.never), ExprIsRead::Yes, ); this.diverges = previous_diverges; @@ -1514,7 +1527,7 @@ impl<'db> InferenceContext<'_, 'db> { } else { this.infer_expr_coerce( expr, - &Expectation::HasType(this.types.unit), + &Expectation::HasType(this.types.types.unit), ExprIsRead::Yes, ); } @@ -1541,7 +1554,7 @@ impl<'db> InferenceContext<'_, 'db> { if this .coerce( expr.into(), - this.types.unit, + this.types.types.unit, t, AllowTwoPhase::No, ExprIsRead::Yes, @@ -1552,13 +1565,13 @@ impl<'db> InferenceContext<'_, 'db> { expr.into(), TypeMismatch { expected: t.store(), - actual: this.types.unit.store(), + actual: this.types.types.unit.store(), }, ); } t } else { - this.types.unit + this.types.types.unit } } }); @@ -1927,7 +1940,7 @@ impl<'db> InferenceContext<'_, 'db> { let (formal_receiver_ty, param_tys) = if !sig.inputs_and_output.inputs().is_empty() { (sig.inputs_and_output.as_slice()[0], &sig.inputs_and_output.inputs()[1..]) } else { - (self.types.error, &[] as _) + (self.types.types.error, &[] as _) }; let ret_ty = sig.output(); self.table.unify(formal_receiver_ty, receiver_ty); diff --git a/crates/hir-ty/src/infer/fallback.rs b/crates/hir-ty/src/infer/fallback.rs index d0ce8cba7a..c7669b346f 100644 --- a/crates/hir-ty/src/infer/fallback.rs +++ b/crates/hir-ty/src/infer/fallback.rs @@ -151,8 +151,8 @@ impl<'db> InferenceContext<'_, 'db> { // type, `?T` is not considered unsolved, but `?I` is. The // same is true for float variables.) let fallback = match ty.kind() { - TyKind::Infer(rustc_type_ir::IntVar(_)) => self.types.i32, - TyKind::Infer(rustc_type_ir::FloatVar(_)) => self.types.f64, + TyKind::Infer(rustc_type_ir::IntVar(_)) => self.types.types.i32, + TyKind::Infer(rustc_type_ir::FloatVar(_)) => self.types.types.f64, _ => match diverging_fallback.get(&ty) { Some(&fallback_ty) => fallback_ty, None => return false, @@ -337,7 +337,7 @@ impl<'db> InferenceContext<'_, 'db> { match behavior { DivergingFallbackBehavior::ToUnit => { debug!("fallback to () - legacy: {:?}", diverging_vid); - fallback_to(self.types.unit); + fallback_to(self.types.types.unit); } DivergingFallbackBehavior::ContextDependent => { // FIXME: rustc does the following, but given this is only relevant when the unstable @@ -368,14 +368,14 @@ impl<'db> InferenceContext<'_, 'db> { // // set, see the relationship finding module in // // compiler/rustc_trait_selection/src/traits/relationships.rs. // debug!("fallback to () - found trait and projection: {:?}", diverging_vid); - // fallback_to(self.types.unit); + // fallback_to(self.types.types.unit); // } if can_reach_non_diverging { debug!("fallback to () - reached non-diverging: {:?}", diverging_vid); - fallback_to(self.types.unit); + fallback_to(self.types.types.unit); } else { debug!("fallback to ! - all diverging: {:?}", diverging_vid); - fallback_to(self.types.never); + fallback_to(self.types.types.never); } } DivergingFallbackBehavior::ToNever => { @@ -383,7 +383,7 @@ impl<'db> InferenceContext<'_, 'db> { "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}", diverging_vid ); - fallback_to(self.types.never); + fallback_to(self.types.types.never); } } } diff --git a/crates/hir-ty/src/infer/op.rs b/crates/hir-ty/src/infer/op.rs index c61b6c9ae5..c79c828cd4 100644 --- a/crates/hir-ty/src/infer/op.rs +++ b/crates/hir-ty/src/infer/op.rs @@ -39,7 +39,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { && is_builtin_binop(lhs_ty, rhs_ty, category) { self.enforce_builtin_binop_types(lhs_ty, rhs_ty, category); - self.types.unit + self.types.types.unit } else { return_ty }; @@ -67,20 +67,20 @@ impl<'a, 'db> InferenceContext<'a, 'db> { // && and || are a simple case. self.infer_expr_coerce( lhs_expr, - &Expectation::HasType(self.types.bool), + &Expectation::HasType(self.types.types.bool), ExprIsRead::Yes, ); let lhs_diverges = self.diverges; self.infer_expr_coerce( rhs_expr, - &Expectation::HasType(self.types.bool), + &Expectation::HasType(self.types.types.bool), ExprIsRead::Yes, ); // Depending on the LHS' value, the RHS can never execute. self.diverges = lhs_diverges; - self.types.bool + self.types.types.bool } _ => { // Otherwise, we always treat operators as if they are @@ -131,9 +131,9 @@ impl<'a, 'db> InferenceContext<'a, 'db> { match category { BinOpCategory::Shortcircuit => { - self.demand_suptype(self.types.bool, lhs_ty); - self.demand_suptype(self.types.bool, rhs_ty); - self.types.bool + self.demand_suptype(self.types.types.bool, lhs_ty); + self.demand_suptype(self.types.types.bool, rhs_ty); + self.types.types.bool } BinOpCategory::Shift => { @@ -150,7 +150,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { BinOpCategory::Comparison => { // both LHS and RHS and result will have the same type self.demand_suptype(lhs_ty, rhs_ty); - self.types.bool + self.types.types.bool } } } @@ -251,7 +251,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { } Err(_errors) => { // FIXME: Report diagnostic. - self.types.error + self.types.types.error } }; @@ -271,7 +271,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { } Err(_errors) => { // FIXME: Report diagnostic. - self.types.error + self.types.types.error } } } diff --git a/crates/hir-ty/src/infer/opaques.rs b/crates/hir-ty/src/infer/opaques.rs index 1c722897f4..a39288721b 100644 --- a/crates/hir-ty/src/infer/opaques.rs +++ b/crates/hir-ty/src/infer/opaques.rs @@ -117,7 +117,7 @@ impl<'db> InferenceContext<'_, 'db> { continue; } - self.result.type_of_opaque.insert(def_id, self.types.error.store()); + self.result.type_of_opaque.insert(def_id, self.types.types.error.store()); } } @@ -139,9 +139,10 @@ impl<'db> InferenceContext<'_, 'db> { let at = self.table.infer_ctxt.at(&cause, self.table.param_env); let hidden_type = match at.deeply_normalize(hidden_type) { Ok(hidden_type) => hidden_type, - Err(_errors) => OpaqueHiddenType { ty: self.types.error }, + Err(_errors) => OpaqueHiddenType { ty: self.types.types.error }, }; - let hidden_type = fold_regions(self.interner(), hidden_type, |_, _| self.types.re_erased); + let hidden_type = + fold_regions(self.interner(), hidden_type, |_, _| self.types.regions.erased); UsageKind::HasDefiningUse(hidden_type) } } diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 5eddd4102b..1b8ce5ceaf 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -234,7 +234,7 @@ impl<'db> InferenceContext<'_, 'db> { } if let Some(uncovered) = elements.get(element_tys.len()..) { for &elem in uncovered { - self.infer_pat(elem, self.types.error, default_bm, decl); + self.infer_pat(elem, self.types.types.error, default_bm, decl); } } pat_ty @@ -375,7 +375,7 @@ impl<'db> InferenceContext<'_, 'db> { Some((adt, subst)) if adt == box_adt => { (subst.type_at(0), subst.as_slice().get(1).and_then(|a| a.as_type())) } - _ => (self.types.error, None), + _ => (self.types.types.error, None), }; let inner_ty = self.infer_pat(*inner, inner_ty, default_bm, decl); @@ -574,10 +574,14 @@ impl<'db> InferenceContext<'_, 'db> { { let inner = self.table.try_structurally_resolve_type(inner); if matches!(inner.kind(), TyKind::Slice(_)) { - let elem_ty = self.types.u8; + let elem_ty = self.types.types.u8; let slice_ty = Ty::new_slice(self.interner(), elem_ty); - let ty = - Ty::new_ref(self.interner(), self.types.re_static, slice_ty, Mutability::Not); + let ty = Ty::new_ref( + self.interner(), + self.types.regions.statik, + slice_ty, + Mutability::Not, + ); self.write_expr_ty(expr, ty); return ty; } diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index a323952494..69e6b40a09 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -102,7 +102,7 @@ impl<'db> InferenceContext<'_, 'db> { // This is something like `TypeAlias::::EnumVariant`. Do not call `substs_from_path()`, // as it'll try to re-lower the previous segment assuming it refers to the enum, but it refers // to the type alias and they may have different generics. - self.types.empty_args + self.types.empty.generic_args } else { self.with_body_ty_lowering(|ctx| { let mut path_ctx = ctx.at_path(path, id); diff --git a/crates/hir-ty/src/infer/place_op.rs b/crates/hir-ty/src/infer/place_op.rs index 5bcae21aa1..1298b38097 100644 --- a/crates/hir-ty/src/infer/place_op.rs +++ b/crates/hir-ty/src/infer/place_op.rs @@ -125,7 +125,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { ctx.interner(), ObligationCause::new(), ctx.table.param_env, - ClauseKind::ConstArgHasType(ct, ctx.types.usize), + ClauseKind::ConstArgHasType(ct, ctx.types.types.usize), )); self_ty = Ty::new_slice(ctx.interner(), element_ty); } else { diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 50f808affa..7c38c83628 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -170,6 +170,7 @@ impl<'db> LifetimeElisionKind<'db> { pub struct TyLoweringContext<'db, 'a> { pub db: &'db dyn HirDatabase, interner: DbInterner<'db>, + types: &'db crate::next_solver::DefaultAny<'db>, lang_items: &'db LangItems, resolver: &'a Resolver<'db>, store: &'a ExpressionStore, @@ -201,6 +202,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { db, // Can provide no block since we don't use it for trait solving. interner, + types: crate::next_solver::default_types(db), lang_items: interner.lang_items(), resolver, def, @@ -399,7 +401,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let type_ref = &self.store[type_ref_id]; tracing::debug!(?type_ref); let ty = match type_ref { - TypeRef::Never => Ty::new(interner, TyKind::Never), + TypeRef::Never => self.types.types.never, TypeRef::Tuple(inner) => { let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr)); Ty::new_tup_from_iter(interner, inner_tys) diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index ca198aa71b..e8d42bed9f 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -80,6 +80,7 @@ struct MirLowerCtx<'a, 'db> { db: &'db dyn HirDatabase, body: &'a Body, infer: &'a InferenceResult, + types: &'db crate::next_solver::DefaultAny<'db>, resolver: Resolver<'db>, drop_scopes: Vec, env: ParamEnv<'db>, @@ -312,6 +313,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { db, infer, body, + types: crate::next_solver::default_types(db), owner, resolver, current_loop_blocks: None, @@ -369,11 +371,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { match adjustments.split_last() { Some((last, rest)) => match &last.kind { Adjust::NeverToAny => { - let temp = self.temp( - Ty::new(self.interner(), TyKind::Never), - current, - MirSpan::Unknown, - )?; + let temp = self.temp(self.types.types.never, current, MirSpan::Unknown)?; self.lower_expr_to_place_with_adjust(expr_id, temp.into(), current, rest) } Adjust::Deref(_) => { diff --git a/crates/hir-ty/src/next_solver.rs b/crates/hir-ty/src/next_solver.rs index e91864bd87..298af7d124 100644 --- a/crates/hir-ty/src/next_solver.rs +++ b/crates/hir-ty/src/next_solver.rs @@ -26,6 +26,8 @@ mod structural_normalize; mod ty; pub mod util; +use std::{mem::ManuallyDrop, sync::OnceLock}; + pub use binder::*; pub use consts::*; pub use def_id::*; @@ -37,6 +39,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; @@ -53,3 +56,225 @@ pub type TypingMode<'db> = rustc_type_ir::TypingMode>; pub type TypeError<'db> = rustc_type_ir::error::TypeError>; pub type QueryResult<'db> = rustc_type_ir::solve::QueryResult>; pub type FxIndexMap = rustc_type_ir::data_structures::IndexMap; + +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> = 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), + ]), + } + }) +} diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs index c2fc4d18bb..9643f1ba4c 100644 --- a/crates/hir-ty/src/next_solver/consts.rs +++ b/crates/hir-ty/src/next_solver/consts.rs @@ -64,7 +64,7 @@ impl<'db> Const<'db> { } pub fn error(interner: DbInterner<'db>) -> Self { - Const::new(interner, ConstKind::Error(ErrorGuaranteed)) + interner.default_types().consts.error } pub fn new_param(interner: DbInterner<'db>, param: ParamConst) -> Self { @@ -421,8 +421,8 @@ impl<'db> rustc_type_ir::inherent::Const> for Const<'db> { Const::new(interner, ConstKind::Expr(expr)) } - fn new_error(interner: DbInterner<'db>, guar: ErrorGuaranteed) -> Self { - Const::new(interner, ConstKind::Error(guar)) + fn new_error(interner: DbInterner<'db>, _guar: ErrorGuaranteed) -> Self { + Const::error(interner) } } diff --git a/crates/hir-ty/src/next_solver/generic_arg.rs b/crates/hir-ty/src/next_solver/generic_arg.rs index 785d3ef652..6eee7cc27a 100644 --- a/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/crates/hir-ty/src/next_solver/generic_arg.rs @@ -22,7 +22,7 @@ use smallvec::SmallVec; use crate::next_solver::{ ConstInterned, PolyFnSig, RegionInterned, TyInterned, impl_foldable_for_interned_slice, - impl_stored_interned_slice, interned_slice, + interned_slice, }; use super::{ @@ -446,9 +446,15 @@ impl<'db> Relate> for GenericArg<'db> { } } -interned_slice!(GenericArgsStorage, GenericArgs, GenericArg<'db>, GenericArg<'static>,); +interned_slice!( + GenericArgsStorage, + GenericArgs, + StoredGenericArgs, + generic_args, + GenericArg<'db>, + GenericArg<'static>, +); impl_foldable_for_interned_slice!(GenericArgs); -impl_stored_interned_slice!(GenericArgsStorage, GenericArgs, StoredGenericArgs); impl<'db> rustc_type_ir::inherent::GenericArg> for GenericArg<'db> {} diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs index 0102c2ef6e..fcda02b1fa 100644 --- a/crates/hir-ty/src/next_solver/interner.rs +++ b/crates/hir-ty/src/next_solver/interner.rs @@ -60,7 +60,7 @@ use super::{ }; macro_rules! interned_slice { - ($storage:ident, $name:ident, $ty_db:ty, $ty_static:ty $(,)?) => { + ($storage:ident, $name:ident, $stored_name:ident, $default_types_field:ident, $ty_db:ty, $ty_static:ty $(,)?) => { const _: () = { #[allow(unused_lifetimes)] fn _ensure_correct_types<'db: 'static>(v: $ty_db) -> $ty_static { v } @@ -81,9 +81,8 @@ macro_rules! interned_slice { impl<'db> $name<'db> { #[inline] - pub fn empty(_interner: DbInterner<'db>) -> Self { - // FIXME: Get from a static. - Self::new_from_slice(&[]) + pub fn empty(interner: DbInterner<'db>) -> Self { + interner.default_types().empty.$default_types_field } #[inline] @@ -175,41 +174,12 @@ macro_rules! interned_slice { } } } + + $crate::next_solver::interner::impl_stored_interned_slice!($storage, $name, $stored_name); }; } pub(crate) use interned_slice; -macro_rules! impl_foldable_for_interned_slice { - ($name:ident) => { - impl<'db> ::rustc_type_ir::TypeVisitable> for $name<'db> { - fn visit_with>>( - &self, - visitor: &mut V, - ) -> V::Result { - use rustc_ast_ir::visit::VisitorResult; - rustc_ast_ir::walk_visitable_list!(visitor, (*self).iter()); - V::Result::output() - } - } - - impl<'db> rustc_type_ir::TypeFoldable> for $name<'db> { - fn try_fold_with>>( - self, - folder: &mut F, - ) -> Result { - Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder))) - } - fn fold_with>>( - self, - folder: &mut F, - ) -> Self { - Self::new_from_iter(folder.cx(), self.iter().map(|it| it.fold_with(folder))) - } - } - }; -} -pub(crate) use impl_foldable_for_interned_slice; - macro_rules! impl_stored_interned_slice { ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => { #[derive(Clone, PartialEq, Eq, Hash)] @@ -254,6 +224,37 @@ macro_rules! impl_stored_interned_slice { } pub(crate) use impl_stored_interned_slice; +macro_rules! impl_foldable_for_interned_slice { + ($name:ident) => { + impl<'db> ::rustc_type_ir::TypeVisitable> for $name<'db> { + fn visit_with>>( + &self, + visitor: &mut V, + ) -> V::Result { + use rustc_ast_ir::visit::VisitorResult; + rustc_ast_ir::walk_visitable_list!(visitor, (*self).iter()); + V::Result::output() + } + } + + impl<'db> rustc_type_ir::TypeFoldable> for $name<'db> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder))) + } + fn fold_with>>( + self, + folder: &mut F, + ) -> Self { + Self::new_from_iter(folder.cx(), self.iter().map(|it| it.fold_with(folder))) + } + } + }; +} +pub(crate) use impl_foldable_for_interned_slice; + macro_rules! impl_stored_interned { ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => { #[derive(Clone, PartialEq, Eq, Hash)] @@ -362,6 +363,11 @@ impl<'db> DbInterner<'db> { where you should've called `DbInterner::new_with()`", ) } + + #[inline] + pub fn default_types<'a>(&self) -> &'a crate::next_solver::DefaultAny<'db> { + crate::next_solver::default_types(self.db) + } } // This is intentionally left as `()` @@ -374,8 +380,14 @@ impl<'db> inherent::Span> for Span { } } -interned_slice!(BoundVarKindsStorage, BoundVarKinds, BoundVarKind, BoundVarKind); -impl_stored_interned_slice!(BoundVarKindsStorage, BoundVarKinds, StoredBoundVarKinds); +interned_slice!( + BoundVarKindsStorage, + BoundVarKinds, + StoredBoundVarKinds, + bound_var_kinds, + BoundVarKind, + BoundVarKind, +); #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum BoundVarKind { @@ -410,6 +422,8 @@ impl BoundVarKind { interned_slice!( CanonicalVarsStorage, CanonicalVars, + StoredCanonicalVars, + canonical_vars, CanonicalVarKind<'db>, CanonicalVarKind<'static> ); @@ -438,8 +452,7 @@ impl std::fmt::Debug for Placeholder { #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct AllocId; -interned_slice!(VariancesOfStorage, VariancesOf, Variance, Variance); -impl_stored_interned_slice!(VariancesOfStorage, VariancesOf, StoredVariancesOf); +interned_slice!(VariancesOfStorage, VariancesOf, StoredVariancesOf, variances, Variance, Variance); #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct VariantIdx(usize); @@ -949,7 +962,7 @@ impl<'db> rustc_type_ir::relate::Relate> for Pattern<'db> { } } -interned_slice!(PatListStorage, PatList, Pattern<'db>, Pattern<'static>); +interned_slice!(PatListStorage, PatList, StoredPatList, pat_list, Pattern<'db>, Pattern<'static>); impl_foldable_for_interned_slice!(PatList); macro_rules! as_lang_item { diff --git a/crates/hir-ty/src/next_solver/opaques.rs b/crates/hir-ty/src/next_solver/opaques.rs index 230469c21a..bdb3f30871 100644 --- a/crates/hir-ty/src/next_solver/opaques.rs +++ b/crates/hir-ty/src/next_solver/opaques.rs @@ -15,6 +15,8 @@ type PredefinedOpaque<'db> = (OpaqueTypeKey<'db>, Ty<'db>); interned_slice!( PredefinedOpaquesStorage, PredefinedOpaques, + StoredPredefinedOpaques, + predefined_opaques, PredefinedOpaque<'db>, PredefinedOpaque<'static>, ); @@ -23,7 +25,14 @@ impl_foldable_for_interned_slice!(PredefinedOpaques); pub type ExternalConstraintsData<'db> = rustc_type_ir::solve::ExternalConstraintsData>; -interned_slice!(SolverDefIdsStorage, SolverDefIds, SolverDefId, SolverDefId); +interned_slice!( + SolverDefIdsStorage, + SolverDefIds, + StoredSolverDefIds, + def_ids, + SolverDefId, + SolverDefId, +); impl_foldable_for_interned_slice!(SolverDefIds); #[derive(Clone, Copy, PartialEq, Eq, Hash)] diff --git a/crates/hir-ty/src/next_solver/predicate.rs b/crates/hir-ty/src/next_solver/predicate.rs index 6d7539575f..5758e2dc7e 100644 --- a/crates/hir-ty/src/next_solver/predicate.rs +++ b/crates/hir-ty/src/next_solver/predicate.rs @@ -76,6 +76,8 @@ fn stable_cmp_existential_predicate<'db>( interned_slice!( BoundExistentialPredicatesStorage, BoundExistentialPredicates, + StoredBoundExistentialPredicates, + bound_existential_predicates, BoundExistentialPredicate<'db>, BoundExistentialPredicate<'static>, ); diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs index e34e87601f..dc2441f76e 100644 --- a/crates/hir-ty/src/next_solver/region.rs +++ b/crates/hir-ty/src/next_solver/region.rs @@ -11,11 +11,12 @@ use rustc_type_ir::{ }; use crate::next_solver::{ - GenericArg, OutlivesPredicate, impl_foldable_for_interned_slice, interned_slice, + GenericArg, OutlivesPredicate, impl_foldable_for_interned_slice, impl_stored_interned, + interned_slice, }; use super::{ - ErrorGuaranteed, SolverDefId, + SolverDefId, interner::{BoundVarKind, DbInterner, Placeholder}, }; @@ -31,6 +32,7 @@ pub struct Region<'db> { pub(super) struct RegionInterned(RegionKind<'static>); impl_internable!(gc; RegionInterned); +impl_stored_interned!(RegionInterned, Region, StoredRegion); const _: () = { const fn is_copy() {} @@ -64,7 +66,7 @@ impl<'db> Region<'db> { } pub fn new_erased(interner: DbInterner<'db>) -> Region<'db> { - Region::new(interner, RegionKind::ReErased) + interner.default_types().regions.erased } pub fn new_bound( @@ -96,7 +98,7 @@ impl<'db> Region<'db> { } pub fn error(interner: DbInterner<'db>) -> Self { - Region::new(interner, RegionKind::ReError(ErrorGuaranteed)) + interner.default_types().regions.error } pub fn type_flags(&self) -> TypeFlags { @@ -352,7 +354,7 @@ impl<'db> rustc_type_ir::inherent::Region> for Region<'db> { } fn new_static(interner: DbInterner<'db>) -> Self { - Region::new(interner, RegionKind::ReStatic) + interner.default_types().regions.statik } fn new_placeholder( @@ -400,6 +402,8 @@ type GenericArgOutlivesPredicate<'db> = OutlivesPredicate<'db, GenericArg<'db>>; interned_slice!( RegionAssumptionsStorage, RegionAssumptions, + StoredRegionAssumptions, + region_assumptions, GenericArgOutlivesPredicate<'db>, GenericArgOutlivesPredicate<'static>, ); diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs index 87cba7aca8..ee460aff44 100644 --- a/crates/hir-ty/src/next_solver/ty.rs +++ b/crates/hir-ty/src/next_solver/ty.rs @@ -32,8 +32,7 @@ use crate::{ AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const, CoroutineIdWrapper, FnSig, GenericArgKind, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper, abi::Safety, - impl_foldable_for_interned_slice, impl_stored_interned, impl_stored_interned_slice, - interned_slice, + impl_foldable_for_interned_slice, impl_stored_interned, interned_slice, util::{CoroutineArgsExt, IntegerTypeExt}, }, }; @@ -112,16 +111,39 @@ impl<'db> Ty<'db> { Ty::new_infer(interner, InferTy::FloatVar(v)) } + #[inline] pub fn new_int(interner: DbInterner<'db>, i: IntTy) -> Self { - Ty::new(interner, TyKind::Int(i)) + let types = interner.default_types(); + match i { + IntTy::Isize => types.types.isize, + IntTy::I8 => types.types.i8, + IntTy::I16 => types.types.i16, + IntTy::I32 => types.types.i32, + IntTy::I64 => types.types.i64, + IntTy::I128 => types.types.i128, + } } pub fn new_uint(interner: DbInterner<'db>, ui: UintTy) -> Self { - Ty::new(interner, TyKind::Uint(ui)) + let types = interner.default_types(); + match ui { + UintTy::Usize => types.types.usize, + UintTy::U8 => types.types.u8, + UintTy::U16 => types.types.u16, + UintTy::U32 => types.types.u32, + UintTy::U64 => types.types.u64, + UintTy::U128 => types.types.u128, + } } pub fn new_float(interner: DbInterner<'db>, f: FloatTy) -> Self { - Ty::new(interner, TyKind::Float(f)) + let types = interner.default_types(); + match f { + FloatTy::F16 => types.types.f16, + FloatTy::F32 => types.types.f32, + FloatTy::F64 => types.types.f64, + FloatTy::F128 => types.types.f128, + } } pub fn new_fresh(interner: DbInterner<'db>, n: u32) -> Self { @@ -137,7 +159,7 @@ impl<'db> Ty<'db> { } pub fn new_empty_tuple(interner: DbInterner<'db>) -> Self { - Ty::new_tup(interner, &[]) + interner.default_types().types.unit } pub fn new_imm_ptr(interner: DbInterner<'db>, ty: Ty<'db>) -> Self { @@ -568,34 +590,34 @@ impl<'db> Ty<'db> { interner: DbInterner<'db>, ty: hir_def::builtin_type::BuiltinType, ) -> Ty<'db> { - let kind = match ty { - hir_def::builtin_type::BuiltinType::Char => TyKind::Char, - hir_def::builtin_type::BuiltinType::Bool => TyKind::Bool, - hir_def::builtin_type::BuiltinType::Str => TyKind::Str, - hir_def::builtin_type::BuiltinType::Int(int) => TyKind::Int(match int { - hir_def::builtin_type::BuiltinInt::Isize => rustc_type_ir::IntTy::Isize, - hir_def::builtin_type::BuiltinInt::I8 => rustc_type_ir::IntTy::I8, - hir_def::builtin_type::BuiltinInt::I16 => rustc_type_ir::IntTy::I16, - hir_def::builtin_type::BuiltinInt::I32 => rustc_type_ir::IntTy::I32, - hir_def::builtin_type::BuiltinInt::I64 => rustc_type_ir::IntTy::I64, - hir_def::builtin_type::BuiltinInt::I128 => rustc_type_ir::IntTy::I128, - }), - hir_def::builtin_type::BuiltinType::Uint(uint) => TyKind::Uint(match uint { - hir_def::builtin_type::BuiltinUint::Usize => rustc_type_ir::UintTy::Usize, - hir_def::builtin_type::BuiltinUint::U8 => rustc_type_ir::UintTy::U8, - hir_def::builtin_type::BuiltinUint::U16 => rustc_type_ir::UintTy::U16, - hir_def::builtin_type::BuiltinUint::U32 => rustc_type_ir::UintTy::U32, - hir_def::builtin_type::BuiltinUint::U64 => rustc_type_ir::UintTy::U64, - hir_def::builtin_type::BuiltinUint::U128 => rustc_type_ir::UintTy::U128, - }), - hir_def::builtin_type::BuiltinType::Float(float) => TyKind::Float(match float { - hir_def::builtin_type::BuiltinFloat::F16 => rustc_type_ir::FloatTy::F16, - hir_def::builtin_type::BuiltinFloat::F32 => rustc_type_ir::FloatTy::F32, - hir_def::builtin_type::BuiltinFloat::F64 => rustc_type_ir::FloatTy::F64, - hir_def::builtin_type::BuiltinFloat::F128 => rustc_type_ir::FloatTy::F128, - }), - }; - Ty::new(interner, kind) + let types = interner.default_types(); + match ty { + hir_def::builtin_type::BuiltinType::Char => types.types.char, + hir_def::builtin_type::BuiltinType::Bool => types.types.bool, + hir_def::builtin_type::BuiltinType::Str => types.types.str, + hir_def::builtin_type::BuiltinType::Int(int) => match int { + hir_def::builtin_type::BuiltinInt::Isize => types.types.isize, + hir_def::builtin_type::BuiltinInt::I8 => types.types.i8, + hir_def::builtin_type::BuiltinInt::I16 => types.types.i16, + hir_def::builtin_type::BuiltinInt::I32 => types.types.i32, + hir_def::builtin_type::BuiltinInt::I64 => types.types.i64, + hir_def::builtin_type::BuiltinInt::I128 => types.types.i128, + }, + hir_def::builtin_type::BuiltinType::Uint(uint) => match uint { + hir_def::builtin_type::BuiltinUint::Usize => types.types.usize, + hir_def::builtin_type::BuiltinUint::U8 => types.types.u8, + hir_def::builtin_type::BuiltinUint::U16 => types.types.u16, + hir_def::builtin_type::BuiltinUint::U32 => types.types.u32, + hir_def::builtin_type::BuiltinUint::U64 => types.types.u64, + hir_def::builtin_type::BuiltinUint::U128 => types.types.u128, + }, + hir_def::builtin_type::BuiltinType::Float(float) => match float { + hir_def::builtin_type::BuiltinFloat::F16 => types.types.f16, + hir_def::builtin_type::BuiltinFloat::F32 => types.types.f32, + hir_def::builtin_type::BuiltinFloat::F64 => types.types.f64, + hir_def::builtin_type::BuiltinFloat::F128 => types.types.f128, + }, + } } pub fn as_builtin(self) -> Option { @@ -955,19 +977,19 @@ impl<'db> Flags for Ty<'db> { impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { fn new_unit(interner: DbInterner<'db>) -> Self { - Ty::new(interner, TyKind::Tuple(Default::default())) + interner.default_types().types.unit } fn new_bool(interner: DbInterner<'db>) -> Self { - Ty::new(interner, TyKind::Bool) + interner.default_types().types.bool } fn new_u8(interner: DbInterner<'db>) -> Self { - Ty::new(interner, TyKind::Uint(rustc_type_ir::UintTy::U8)) + interner.default_types().types.u8 } fn new_usize(interner: DbInterner<'db>) -> Self { - Ty::new(interner, TyKind::Uint(rustc_type_ir::UintTy::Usize)) + interner.default_types().types.usize } fn new_infer(interner: DbInterner<'db>, var: rustc_type_ir::InferTy) -> Self { @@ -1118,7 +1140,7 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { } fn new_tup(interner: DbInterner<'db>, tys: &[ as Interner>::Ty]) -> Self { - Ty::new(interner, TyKind::Tuple(Tys::new_from_iter(interner, tys.iter().cloned()))) + Ty::new(interner, TyKind::Tuple(Tys::new_from_slice(tys))) } fn new_tup_from_iter(interner: DbInterner<'db>, iter: It) -> T::Output @@ -1190,10 +1212,11 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { } fn from_closure_kind(interner: DbInterner<'db>, kind: rustc_type_ir::ClosureKind) -> Self { + let types = interner.default_types(); match kind { - ClosureKind::Fn => Ty::new(interner, TyKind::Int(IntTy::I8)), - ClosureKind::FnMut => Ty::new(interner, TyKind::Int(IntTy::I16)), - ClosureKind::FnOnce => Ty::new(interner, TyKind::Int(IntTy::I32)), + ClosureKind::Fn => types.types.i8, + ClosureKind::FnMut => types.types.i16, + ClosureKind::FnOnce => types.types.i32, } } @@ -1201,9 +1224,10 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { interner: DbInterner<'db>, kind: rustc_type_ir::ClosureKind, ) -> Self { + let types = interner.default_types(); match kind { - ClosureKind::Fn | ClosureKind::FnMut => Ty::new(interner, TyKind::Int(IntTy::I16)), - ClosureKind::FnOnce => Ty::new(interner, TyKind::Int(IntTy::I32)), + ClosureKind::Fn | ClosureKind::FnMut => types.types.i16, + ClosureKind::FnOnce => types.types.i32, } } @@ -1250,7 +1274,7 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { | TyKind::Tuple(_) | TyKind::Error(_) | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_)) => { - Ty::new(interner, TyKind::Uint(UintTy::U8)) + interner.default_types().types.u8 } TyKind::Bound(..) @@ -1267,9 +1291,8 @@ impl<'db> rustc_type_ir::inherent::Ty> for Ty<'db> { } } -interned_slice!(TysStorage, Tys, Ty<'db>, Ty<'static>); +interned_slice!(TysStorage, Tys, StoredTys, tys, Ty<'db>, Ty<'static>); impl_foldable_for_interned_slice!(Tys); -impl_stored_interned_slice!(TysStorage, Tys, StoredTys); impl<'db> Tys<'db> { #[inline] diff --git a/crates/hir-ty/src/next_solver/util.rs b/crates/hir-ty/src/next_solver/util.rs index bc4b5fdbfc..34ecfed08f 100644 --- a/crates/hir-ty/src/next_solver/util.rs +++ b/crates/hir-ty/src/next_solver/util.rs @@ -77,9 +77,10 @@ pub trait IntegerTypeExt { impl IntegerTypeExt for IntegerType { fn to_ty<'db>(&self, interner: DbInterner<'db>) -> Ty<'db> { + let types = interner.default_types(); match self { - IntegerType::Pointer(true) => Ty::new(interner, TyKind::Int(IntTy::Isize)), - IntegerType::Pointer(false) => Ty::new(interner, TyKind::Uint(UintTy::Usize)), + IntegerType::Pointer(true) => types.types.isize, + IntegerType::Pointer(false) => types.types.usize, IntegerType::Fixed(i, s) => i.to_ty(interner, *s), } } @@ -120,17 +121,18 @@ impl IntegerExt for Integer { #[inline] fn to_ty<'db>(&self, interner: DbInterner<'db>, signed: bool) -> Ty<'db> { use Integer::*; + let types = interner.default_types(); match (*self, signed) { - (I8, false) => Ty::new(interner, TyKind::Uint(UintTy::U8)), - (I16, false) => Ty::new(interner, TyKind::Uint(UintTy::U16)), - (I32, false) => Ty::new(interner, TyKind::Uint(UintTy::U32)), - (I64, false) => Ty::new(interner, TyKind::Uint(UintTy::U64)), - (I128, false) => Ty::new(interner, TyKind::Uint(UintTy::U128)), - (I8, true) => Ty::new(interner, TyKind::Int(IntTy::I8)), - (I16, true) => Ty::new(interner, TyKind::Int(IntTy::I16)), - (I32, true) => Ty::new(interner, TyKind::Int(IntTy::I32)), - (I64, true) => Ty::new(interner, TyKind::Int(IntTy::I64)), - (I128, true) => Ty::new(interner, TyKind::Int(IntTy::I128)), + (I8, false) => types.types.u8, + (I16, false) => types.types.u16, + (I32, false) => types.types.u32, + (I64, false) => types.types.u64, + (I128, false) => types.types.u128, + (I8, true) => types.types.i8, + (I16, true) => types.types.i16, + (I32, true) => types.types.i32, + (I64, true) => types.types.i64, + (I128, true) => types.types.i128, } } @@ -214,11 +216,12 @@ impl FloatExt for Float { #[inline] fn to_ty<'db>(&self, interner: DbInterner<'db>) -> Ty<'db> { use Float::*; + let types = interner.default_types(); match *self { - F16 => Ty::new(interner, TyKind::Float(FloatTy::F16)), - F32 => Ty::new(interner, TyKind::Float(FloatTy::F32)), - F64 => Ty::new(interner, TyKind::Float(FloatTy::F64)), - F128 => Ty::new(interner, TyKind::Float(FloatTy::F128)), + F16 => types.types.f16, + F32 => types.types.f32, + F64 => types.types.f64, + F128 => types.types.f128, } } @@ -244,13 +247,7 @@ impl PrimitiveExt for Primitive { match *self { Primitive::Int(i, signed) => i.to_ty(interner, signed), Primitive::Float(f) => f.to_ty(interner), - Primitive::Pointer(_) => Ty::new( - interner, - TyKind::RawPtr( - Ty::new(interner, TyKind::Tuple(Default::default())), - rustc_ast_ir::Mutability::Mut, - ), - ), + Primitive::Pointer(_) => interner.default_types().types.mut_unit_ptr, } } @@ -283,7 +280,7 @@ impl<'db> CoroutineArgsExt<'db> for CoroutineArgs> { /// The type of the state discriminant used in the coroutine type. #[inline] fn discr_ty(&self, interner: DbInterner<'db>) -> Ty<'db> { - Ty::new(interner, TyKind::Uint(UintTy::U32)) + interner.default_types().types.u32 } } diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index bfb9a3f77e..a050124c90 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -48,10 +48,11 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance GenericDefId::AdtId(adt) => { if let AdtId::StructId(id) = adt { let flags = &db.struct_signature(id).flags; + let types = || crate::next_solver::default_types(db); if flags.contains(StructFlags::IS_UNSAFE_CELL) { - return VariancesOf::new_from_iter(interner, [Variance::Invariant]).store(); + return types().one_invariant.store(); } else if flags.contains(StructFlags::IS_PHANTOM_DATA) { - return VariancesOf::new_from_iter(interner, [Variance::Covariant]).store(); + return types().one_covariant.store(); } } }