about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_type_ir/src/fold.rs53
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
+        }
+    }
 }