Pre-intern some TyKind::Bound values.

We already do the same thing for bound regions. This is a small perf win
for the new trait solver.
This commit is contained in:
Nicholas Nethercote 2025-07-25 10:48:21 +10:00
parent bc64bfd75b
commit 837b6106a3
2 changed files with 30 additions and 1 deletions

View file

@ -1041,6 +1041,8 @@ const NUM_PREINTERNED_TY_VARS: u32 = 100;
const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
// This number may seem high, but it is reached in all but the smallest crates.
const NUM_PREINTERNED_RE_VARS: u32 = 500;
@ -1088,6 +1090,11 @@ pub struct CommonTypes<'tcx> {
/// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`.
pub fresh_float_tys: Vec<Ty<'tcx>>,
/// Pre-interned values of the form:
/// `Bound(DebruijnIndex(i), BoundTy { var: v, kind: BoundTyKind::Anon})`
/// for small values of `i` and `v`.
pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
}
pub struct CommonLifetimes<'tcx> {
@ -1131,6 +1138,19 @@ impl<'tcx> CommonTypes<'tcx> {
let fresh_float_tys: Vec<_> =
(0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect();
let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I)
.map(|i| {
(0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
.map(|v| {
mk(ty::Bound(
ty::DebruijnIndex::from(i),
ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
))
})
.collect()
})
.collect();
CommonTypes {
unit: mk(Tuple(List::empty())),
bool: mk(Bool),
@ -1161,6 +1181,7 @@ impl<'tcx> CommonTypes<'tcx> {
fresh_tys,
fresh_int_tys,
fresh_float_tys,
anon_bound_tys,
}
}
}

View file

@ -485,7 +485,15 @@ impl<'tcx> Ty<'tcx> {
index: ty::DebruijnIndex,
bound_ty: ty::BoundTy,
) -> Ty<'tcx> {
Ty::new(tcx, Bound(index, bound_ty))
// Use a pre-interned one when possible.
if let ty::BoundTy { var, kind: ty::BoundTyKind::Anon } = bound_ty
&& let Some(inner) = tcx.types.anon_bound_tys.get(index.as_usize())
&& let Some(ty) = inner.get(var.as_usize()).copied()
{
ty
} else {
Ty::new(tcx, Bound(index, bound_ty))
}
}
#[inline]