44
44
//! - u.fold_with(folder)
45
45
//! ```
46
46
use crate :: mir;
47
- use crate :: ty:: { self , Binder , Ty , TyCtxt , TypeVisitable } ;
47
+ use crate :: ty:: { self , Binder , BoundTy , Ty , TyCtxt , TypeVisitable } ;
48
+ use rustc_data_structures:: fx:: FxIndexMap ;
48
49
use rustc_hir:: def_id:: DefId ;
49
50
50
51
use std:: collections:: BTreeMap ;
@@ -533,12 +534,12 @@ impl<'tcx> TyCtxt<'tcx> {
533
534
pub fn replace_escaping_bound_vars_uncached < T : TypeFoldable < ' tcx > > (
534
535
self ,
535
536
value : T ,
536
- mut delegate : impl BoundVarReplacerDelegate < ' tcx > ,
537
+ delegate : & mut impl BoundVarReplacerDelegate < ' tcx > ,
537
538
) -> T {
538
539
if !value. has_escaping_bound_vars ( ) {
539
540
value
540
541
} else {
541
- let mut replacer = BoundVarReplacer :: new ( self , & mut delegate) ;
542
+ let mut replacer = BoundVarReplacer :: new ( self , delegate) ;
542
543
value. fold_with ( & mut replacer)
543
544
}
544
545
}
@@ -549,9 +550,9 @@ impl<'tcx> TyCtxt<'tcx> {
549
550
pub fn replace_bound_vars_uncached < T : TypeFoldable < ' tcx > > (
550
551
self ,
551
552
value : Binder < ' tcx , T > ,
552
- delegate : impl BoundVarReplacerDelegate < ' tcx > ,
553
+ mut delegate : impl BoundVarReplacerDelegate < ' tcx > ,
553
554
) -> T {
554
- self . replace_escaping_bound_vars_uncached ( value. skip_binder ( ) , delegate)
555
+ self . replace_escaping_bound_vars_uncached ( value. skip_binder ( ) , & mut delegate)
555
556
}
556
557
557
558
/// Replaces any late-bound regions bound in `value` with
@@ -579,7 +580,7 @@ impl<'tcx> TyCtxt<'tcx> {
579
580
let shift_bv = |bv : ty:: BoundVar | ty:: BoundVar :: from_usize ( bv. as_usize ( ) + bound_vars) ;
580
581
self . replace_escaping_bound_vars_uncached (
581
582
value,
582
- FnMutDelegate {
583
+ & mut FnMutDelegate {
583
584
regions : |r : ty:: BoundRegion | {
584
585
self . mk_region ( ty:: ReLateBound (
585
586
ty:: INNERMOST ,
@@ -640,6 +641,50 @@ impl<'tcx> TyCtxt<'tcx> {
640
641
) ;
641
642
Binder :: bind_with_vars ( inner, bound_vars)
642
643
}
644
+
645
+ /// Anonymize all bound variables in `value`, this is mostly used to improve caching.
646
+ pub fn anonymize_bound_vars < T > ( self , value : Binder < ' tcx , T > ) -> Binder < ' tcx , T >
647
+ where
648
+ T : TypeFoldable < ' tcx > ,
649
+ {
650
+ struct Anonymize < ' tcx > {
651
+ tcx : TyCtxt < ' tcx > ,
652
+ map : FxIndexMap < ty:: BoundVar , ty:: BoundVariableKind > ,
653
+ }
654
+ impl < ' tcx > BoundVarReplacerDelegate < ' tcx > for Anonymize < ' tcx > {
655
+ fn replace_region ( & mut self , br : ty:: BoundRegion ) -> ty:: Region < ' tcx > {
656
+ let entry = self . map . entry ( br. var ) ;
657
+ let index = entry. index ( ) ;
658
+ let var = ty:: BoundVar :: from_usize ( index) ;
659
+ let kind = entry
660
+ . or_insert_with ( || ty:: BoundVariableKind :: Region ( ty:: BrAnon ( index as u32 ) ) )
661
+ . expect_region ( ) ;
662
+ let br = ty:: BoundRegion { var, kind } ;
663
+ self . tcx . mk_region ( ty:: ReLateBound ( ty:: INNERMOST , br) )
664
+ }
665
+ fn replace_ty ( & mut self , bt : ty:: BoundTy ) -> Ty < ' tcx > {
666
+ let entry = self . map . entry ( bt. var ) ;
667
+ let index = entry. index ( ) ;
668
+ let var = ty:: BoundVar :: from_usize ( index) ;
669
+ let kind = entry
670
+ . or_insert_with ( || ty:: BoundVariableKind :: Ty ( ty:: BoundTyKind :: Anon ) )
671
+ . expect_ty ( ) ;
672
+ self . tcx . mk_ty ( ty:: Bound ( ty:: INNERMOST , BoundTy { var, kind } ) )
673
+ }
674
+ fn replace_const ( & mut self , bv : ty:: BoundVar , ty : Ty < ' tcx > ) -> ty:: Const < ' tcx > {
675
+ let entry = self . map . entry ( bv) ;
676
+ let index = entry. index ( ) ;
677
+ let var = ty:: BoundVar :: from_usize ( index) ;
678
+ let ( ) = entry. or_insert_with ( || ty:: BoundVariableKind :: Const ) . expect_const ( ) ;
679
+ self . tcx . mk_const ( ty:: ConstS { ty, kind : ty:: ConstKind :: Bound ( ty:: INNERMOST , var) } )
680
+ }
681
+ }
682
+
683
+ let mut delegate = Anonymize { tcx : self , map : Default :: default ( ) } ;
684
+ let inner = self . replace_escaping_bound_vars_uncached ( value. skip_binder ( ) , & mut delegate) ;
685
+ let bound_vars = self . mk_bound_variable_kinds ( delegate. map . into_values ( ) ) ;
686
+ Binder :: bind_with_vars ( inner, bound_vars)
687
+ }
643
688
}
644
689
645
690
///////////////////////////////////////////////////////////////////////////
0 commit comments