@@ -3,9 +3,10 @@ use std::ops::ControlFlow;
33use derive_where:: derive_where;
44use rustc_type_ir_macros:: { Lift_Generic , TypeFoldable_Generic , TypeVisitable_Generic } ;
55
6+ use crate :: data_structures:: DelayedMap ;
67use crate :: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable , shift_region} ;
78use crate :: inherent:: * ;
8- use crate :: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
9+ use crate :: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor } ;
910use crate :: { self as ty, Interner } ;
1011
1112/// A closure can be modeled as a struct that looks like:
@@ -471,6 +472,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
471472 interner : cx,
472473 region : env_region,
473474 debruijn : ty:: INNERMOST ,
475+ cache : Default :: default ( ) ,
474476 } ) ;
475477 Ty :: new_tup_from_iter (
476478 cx,
@@ -498,13 +500,29 @@ struct FoldEscapingRegions<I: Interner> {
498500 interner : I ,
499501 debruijn : ty:: DebruijnIndex ,
500502 region : I :: Region ,
503+
504+ // Depends on `debruijn` because we may have types with regions of different
505+ // debruijn depths depending on the binders we've entered.
506+ cache : DelayedMap < ( ty:: DebruijnIndex , I :: Ty ) , I :: Ty > ,
501507}
502508
503509impl < I : Interner > TypeFolder < I > for FoldEscapingRegions < I > {
504510 fn cx ( & self ) -> I {
505511 self . interner
506512 }
507513
514+ fn fold_ty ( & mut self , t : I :: Ty ) -> I :: Ty {
515+ if !t. has_vars_bound_at_or_above ( self . debruijn ) {
516+ t
517+ } else if let Some ( & t) = self . cache . get ( & ( self . debruijn , t) ) {
518+ t
519+ } else {
520+ let res = t. super_fold_with ( self ) ;
521+ assert ! ( self . cache. insert( ( self . debruijn, t) , res) ) ;
522+ res
523+ }
524+ }
525+
508526 fn fold_binder < T > ( & mut self , t : ty:: Binder < I , T > ) -> ty:: Binder < I , T >
509527 where
510528 T : TypeFoldable < I > ,
0 commit comments