Auto merge of #139287 - compiler-errors:folder-experiment-1, r=lqd

Folder experiment: Monomorphize region resolver

**NOTE:** This is one of a series of perf experiments that I've come up with while sick in bed. I'm assigning them to lqd b/c you're a good reviewer and you'll hopefully be awake when these experiments finish, lol.

r? lqd

This is actually two tweaks to the `RegionFolder`, monomorphizing its callback and accounting for flags to avoid folding unnecessarily.
This commit is contained in:
bors 2025-04-04 05:41:45 +00:00
commit f174fd716a

View file

@ -54,7 +54,7 @@ use tracing::{debug, instrument};
use crate::inherent::*;
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
use crate::{self as ty, Interner};
use crate::{self as ty, Interner, TypeFlags};
#[cfg(feature = "nightly")]
type Never = !;
@ -438,12 +438,12 @@ where
pub fn fold_regions<I: Interner, T>(
cx: I,
value: T,
mut f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
f: impl FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
) -> T
where
T: TypeFoldable<I>,
{
value.fold_with(&mut RegionFolder::new(cx, &mut f))
value.fold_with(&mut RegionFolder::new(cx, f))
}
/// Folds over the substructure of a type, visiting its component
@ -453,7 +453,7 @@ where
/// new bound regions which are not visited by this visitors as
/// they are not free; only regions that occur free will be
/// visited by `fld_r`.
pub struct RegionFolder<'a, I: Interner> {
pub struct RegionFolder<I, F> {
cx: I,
/// Stores the index of a binder *just outside* the stuff we have
@ -464,20 +464,21 @@ pub struct RegionFolder<'a, I: Interner> {
/// Callback invokes for each free region. The `DebruijnIndex`
/// points to the binder *just outside* the ones we have passed
/// through.
fold_region_fn: &'a mut (dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region + 'a),
fold_region_fn: F,
}
impl<'a, I: Interner> RegionFolder<'a, I> {
impl<I, F> RegionFolder<I, F> {
#[inline]
pub fn new(
cx: I,
fold_region_fn: &'a mut dyn FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
) -> RegionFolder<'a, I> {
pub fn new(cx: I, fold_region_fn: F) -> RegionFolder<I, F> {
RegionFolder { cx, current_index: ty::INNERMOST, fold_region_fn }
}
}
impl<'a, I: Interner> TypeFolder<I> for RegionFolder<'a, I> {
impl<I, F> TypeFolder<I> for RegionFolder<I, F>
where
I: Interner,
F: FnMut(I::Region, ty::DebruijnIndex) -> I::Region,
{
fn cx(&self) -> I {
self.cx
}
@ -502,4 +503,34 @@ impl<'a, I: Interner> TypeFolder<I> for RegionFolder<'a, I> {
}
}
}
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
if t.has_type_flags(
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
) {
t.super_fold_with(self)
} else {
t
}
}
fn fold_const(&mut self, ct: I::Const) -> I::Const {
if ct.has_type_flags(
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
) {
ct.super_fold_with(self)
} else {
ct
}
}
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
if p.has_type_flags(
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_BOUND | TypeFlags::HAS_RE_ERASED,
) {
p.super_fold_with(self)
} else {
p
}
}
}