diff options
| author | bors <bors@rust-lang.org> | 2025-04-04 05:41:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-04-04 05:41:45 +0000 |
| commit | f174fd716a429fa17eb1e98ba4e382f09312f8ad (patch) | |
| tree | 5e2999d475fbfa35593dc66cc3ec972cc36afea3 /compiler | |
| parent | 9e14530c7c27123484658c88c2148a552b01e73b (diff) | |
| parent | 60b742d832b08d63e9c2bae0989c13e32ae4e73c (diff) | |
| download | rust-f174fd716a429fa17eb1e98ba4e382f09312f8ad.tar.gz rust-f174fd716a429fa17eb1e98ba4e382f09312f8ad.zip | |
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.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_type_ir/src/fold.rs | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 0bc8b94bbf4..e58f25f4ce7 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -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 + } + } } |
