about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-26 19:58:17 +0000
committerbors <bors@rust-lang.org>2025-01-26 19:58:17 +0000
commitf85c6de55206dbee5ffedfd821df1503a7b92346 (patch)
treea094a621ce53c790634bb171d0c1f80eeae75164 /compiler
parent01a26c026ddd9f0da0307468b07b003b8759fc4a (diff)
parentd7a6fdc71fb378a7f919ee044fa49f3965ad188c (diff)
Auto merge of #135783 - compiler-errors:cache-in-closure-binder, r=lcnr
Add cache to `FoldEscapingRegions`

Fixes #135780

ty `@lqd` for the tests
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index 10b164eae02..74e4e035c87 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -3,9 +3,10 @@ use std::ops::ControlFlow;
 use derive_where::derive_where;
 use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
 
+use crate::data_structures::DelayedMap;
 use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region};
 use crate::inherent::*;
-use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
+use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use crate::{self as ty, Interner};
 
 /// A closure can be modeled as a struct that looks like:
@@ -471,6 +472,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
                         interner: cx,
                         region: env_region,
                         debruijn: ty::INNERMOST,
+                        cache: Default::default(),
                     });
                 Ty::new_tup_from_iter(
                     cx,
@@ -498,6 +500,10 @@ struct FoldEscapingRegions<I: Interner> {
     interner: I,
     debruijn: ty::DebruijnIndex,
     region: I::Region,
+
+    // Depends on `debruijn` because we may have types with regions of different
+    // debruijn depths depending on the binders we've entered.
+    cache: DelayedMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
 }
 
 impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
@@ -505,6 +511,18 @@ impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
         self.interner
     }
 
+    fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
+        if !t.has_vars_bound_at_or_above(self.debruijn) {
+            t
+        } else if let Some(&t) = self.cache.get(&(self.debruijn, t)) {
+            t
+        } else {
+            let res = t.super_fold_with(self);
+            assert!(self.cache.insert((self.debruijn, t), res));
+            res
+        }
+    }
+
     fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
     where
         T: TypeFoldable<I>,