@@ -3,9 +3,10 @@ use std::ops::ControlFlow;
3
3
use derive_where:: derive_where;
4
4
use rustc_type_ir_macros:: { Lift_Generic , TypeFoldable_Generic , TypeVisitable_Generic } ;
5
5
6
+ use crate :: data_structures:: DelayedMap ;
6
7
use crate :: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable , shift_region} ;
7
8
use crate :: inherent:: * ;
8
- use crate :: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
9
+ use crate :: visit:: { TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor } ;
9
10
use crate :: { self as ty, Interner } ;
10
11
11
12
/// A closure can be modeled as a struct that looks like:
@@ -471,6 +472,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
471
472
interner : cx,
472
473
region : env_region,
473
474
debruijn : ty:: INNERMOST ,
475
+ cache : Default :: default ( ) ,
474
476
} ) ;
475
477
Ty :: new_tup_from_iter (
476
478
cx,
@@ -498,13 +500,29 @@ struct FoldEscapingRegions<I: Interner> {
498
500
interner : I ,
499
501
debruijn : ty:: DebruijnIndex ,
500
502
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 > ,
501
507
}
502
508
503
509
impl < I : Interner > TypeFolder < I > for FoldEscapingRegions < I > {
504
510
fn cx ( & self ) -> I {
505
511
self . interner
506
512
}
507
513
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
+
508
526
fn fold_binder < T > ( & mut self , t : ty:: Binder < I , T > ) -> ty:: Binder < I , T >
509
527
where
510
528
T : TypeFoldable < I > ,
0 commit comments