Pre-intern some common types

This is possible now that they are no longer interned with Salsa.
This commit is contained in:
Chayim Refael Friedman 2025-12-18 03:18:39 +02:00
parent d2a029ae05
commit 096ebb0759
23 changed files with 558 additions and 326 deletions

View File

@ -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<BreakableContext<'db>>,
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)
}
}
}

View File

@ -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(

View File

@ -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 {

View File

@ -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
}
}
}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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
}
}
}

View File

@ -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)
}
}

View File

@ -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;
}

View File

@ -102,7 +102,7 @@ impl<'db> InferenceContext<'_, 'db> {
// This is something like `TypeAlias::<Args>::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);

View File

@ -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 {

View File

@ -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)

View File

@ -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<DropScope>,
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(_) => {

View File

@ -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<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),
]),
}
})
}

View File

@ -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<DbInterner<'db>> 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)
}
}

View File

@ -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<DbInterner<'db>> 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<DbInterner<'db>> for GenericArg<'db> {}

View File

@ -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<DbInterner<'db>> for $name<'db> {
fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
&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<DbInterner<'db>> for $name<'db> {
fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder)))
}
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
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<DbInterner<'db>> for $name<'db> {
fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
&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<DbInterner<'db>> for $name<'db> {
fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder)))
}
fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
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<DbInterner<'db>> 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<T: std::fmt::Debug> std::fmt::Debug for Placeholder<T> {
#[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<DbInterner<'db>> 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 {

View File

@ -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<DbInterner<'db>>;
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)]

View File

@ -76,6 +76,8 @@ fn stable_cmp_existential_predicate<'db>(
interned_slice!(
BoundExistentialPredicatesStorage,
BoundExistentialPredicates,
StoredBoundExistentialPredicates,
bound_existential_predicates,
BoundExistentialPredicate<'db>,
BoundExistentialPredicate<'static>,
);

View File

@ -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<T: 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<DbInterner<'db>> 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>,
);

View File

@ -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<hir_def::builtin_type::BuiltinType> {
@ -955,19 +977,19 @@ impl<'db> Flags for Ty<'db> {
impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> 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<DbInterner<'db>> for Ty<'db> {
}
fn new_tup(interner: DbInterner<'db>, tys: &[<DbInterner<'db> 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<It, T>(interner: DbInterner<'db>, iter: It) -> T::Output
@ -1190,10 +1212,11 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> 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<DbInterner<'db>> 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<DbInterner<'db>> 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<DbInterner<'db>> 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]

View File

@ -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<DbInterner<'db>> {
/// 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
}
}

View File

@ -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();
}
}
}