4444//! - u.fold_with(folder)
4545//! ```
4646use 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 ;
4849use rustc_hir:: def_id:: DefId ;
4950
5051use std:: collections:: BTreeMap ;
@@ -533,12 +534,12 @@ impl<'tcx> TyCtxt<'tcx> {
533534 pub fn replace_escaping_bound_vars_uncached < T : TypeFoldable < ' tcx > > (
534535 self ,
535536 value : T ,
536- mut delegate : impl BoundVarReplacerDelegate < ' tcx > ,
537+ delegate : & mut impl BoundVarReplacerDelegate < ' tcx > ,
537538 ) -> T {
538539 if !value. has_escaping_bound_vars ( ) {
539540 value
540541 } else {
541- let mut replacer = BoundVarReplacer :: new ( self , & mut delegate) ;
542+ let mut replacer = BoundVarReplacer :: new ( self , delegate) ;
542543 value. fold_with ( & mut replacer)
543544 }
544545 }
@@ -549,9 +550,9 @@ impl<'tcx> TyCtxt<'tcx> {
549550 pub fn replace_bound_vars_uncached < T : TypeFoldable < ' tcx > > (
550551 self ,
551552 value : Binder < ' tcx , T > ,
552- delegate : impl BoundVarReplacerDelegate < ' tcx > ,
553+ mut delegate : impl BoundVarReplacerDelegate < ' tcx > ,
553554 ) -> T {
554- self . replace_escaping_bound_vars_uncached ( value. skip_binder ( ) , delegate)
555+ self . replace_escaping_bound_vars_uncached ( value. skip_binder ( ) , & mut delegate)
555556 }
556557
557558 /// Replaces any late-bound regions bound in `value` with
@@ -579,7 +580,7 @@ impl<'tcx> TyCtxt<'tcx> {
579580 let shift_bv = |bv : ty:: BoundVar | ty:: BoundVar :: from_usize ( bv. as_usize ( ) + bound_vars) ;
580581 self . replace_escaping_bound_vars_uncached (
581582 value,
582- FnMutDelegate {
583+ & mut FnMutDelegate {
583584 regions : |r : ty:: BoundRegion | {
584585 self . mk_region ( ty:: ReLateBound (
585586 ty:: INNERMOST ,
@@ -640,6 +641,50 @@ impl<'tcx> TyCtxt<'tcx> {
640641 ) ;
641642 Binder :: bind_with_vars ( inner, bound_vars)
642643 }
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+ }
643688}
644689
645690///////////////////////////////////////////////////////////////////////////
0 commit comments