@@ -656,17 +656,17 @@ struct BoundVarReplacer<'a, 'tcx> {
656656 /// the ones we have visited.
657657 current_index : ty:: DebruijnIndex ,
658658
659- fld_r : Option < & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) > ,
660- fld_t : Option < & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) > ,
661- fld_c : Option < & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> ty:: Const < ' tcx > + ' a ) > ,
659+ fld_r : & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) ,
660+ fld_t : & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) ,
661+ fld_c : & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> ty:: Const < ' tcx > + ' a ) ,
662662}
663663
664664impl < ' a , ' tcx > BoundVarReplacer < ' a , ' tcx > {
665665 fn new (
666666 tcx : TyCtxt < ' tcx > ,
667- fld_r : Option < & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) > ,
668- fld_t : Option < & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) > ,
669- fld_c : Option < & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> ty:: Const < ' tcx > + ' a ) > ,
667+ fld_r : & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) ,
668+ fld_t : & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) ,
669+ fld_c : & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> ty:: Const < ' tcx > + ' a ) ,
670670 ) -> Self {
671671 BoundVarReplacer { tcx, current_index : ty:: INNERMOST , fld_r, fld_t, fld_c }
672672 }
@@ -690,55 +690,42 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
690690 fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
691691 match * t. kind ( ) {
692692 ty:: Bound ( debruijn, bound_ty) if debruijn == self . current_index => {
693- if let Some ( fld_t) = self . fld_t . as_mut ( ) {
694- let ty = fld_t ( bound_ty) ;
695- return ty:: fold:: shift_vars ( self . tcx , ty, self . current_index . as_u32 ( ) ) ;
696- }
697- }
698- _ if t. has_vars_bound_at_or_above ( self . current_index ) => {
699- return t. super_fold_with ( self ) ;
693+ let ty = ( self . fld_t ) ( bound_ty) ;
694+ ty:: fold:: shift_vars ( self . tcx , ty, self . current_index . as_u32 ( ) )
700695 }
701- _ => { }
696+ _ if t. has_vars_bound_at_or_above ( self . current_index ) => t. super_fold_with ( self ) ,
697+ _ => t,
702698 }
703- t
704699 }
705700
706701 fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
707702 match * r {
708703 ty:: ReLateBound ( debruijn, br) if debruijn == self . current_index => {
709- if let Some ( fld_r) = self . fld_r . as_mut ( ) {
710- let region = fld_r ( br) ;
711- return if let ty:: ReLateBound ( debruijn1, br) = * region {
712- // If the callback returns a late-bound region,
713- // that region should always use the INNERMOST
714- // debruijn index. Then we adjust it to the
715- // correct depth.
716- assert_eq ! ( debruijn1, ty:: INNERMOST ) ;
717- self . tcx . mk_region ( ty:: ReLateBound ( debruijn, br) )
718- } else {
719- region
720- } ;
704+ let region = ( self . fld_r ) ( br) ;
705+ if let ty:: ReLateBound ( debruijn1, br) = * region {
706+ // If the callback returns a late-bound region,
707+ // that region should always use the INNERMOST
708+ // debruijn index. Then we adjust it to the
709+ // correct depth.
710+ assert_eq ! ( debruijn1, ty:: INNERMOST ) ;
711+ self . tcx . mk_region ( ty:: ReLateBound ( debruijn, br) )
712+ } else {
713+ region
721714 }
722715 }
723- _ => { }
716+ _ => r ,
724717 }
725- r
726718 }
727719
728720 fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
729721 match ct. val ( ) {
730722 ty:: ConstKind :: Bound ( debruijn, bound_const) if debruijn == self . current_index => {
731- if let Some ( fld_c) = self . fld_c . as_mut ( ) {
732- let ct = fld_c ( bound_const, ct. ty ( ) ) ;
733- return ty:: fold:: shift_vars ( self . tcx , ct, self . current_index . as_u32 ( ) ) ;
734- }
735- }
736- _ if ct. has_vars_bound_at_or_above ( self . current_index ) => {
737- return ct. super_fold_with ( self ) ;
723+ let ct = ( self . fld_c ) ( bound_const, ct. ty ( ) ) ;
724+ ty:: fold:: shift_vars ( self . tcx , ct, self . current_index . as_u32 ( ) )
738725 }
739- _ => { }
726+ _ if ct. has_vars_bound_at_or_above ( self . current_index ) => ct. super_fold_with ( self ) ,
727+ _ => ct,
740728 }
741- ct
742729 }
743730}
744731
@@ -752,8 +739,10 @@ impl<'tcx> TyCtxt<'tcx> {
752739 /// returned at the end with each bound region and the free region
753740 /// that replaced it.
754741 ///
755- /// This method only replaces late bound regions and the result may still
756- /// contain escaping bound types.
742+ /// # Panics
743+ ///
744+ /// This method only replaces late bound regions. Any types or
745+ /// constants bound by `value` will cause an ICE.
757746 pub fn replace_late_bound_regions < T , F > (
758747 self ,
759748 value : Binder < ' tcx , T > ,
@@ -766,11 +755,14 @@ impl<'tcx> TyCtxt<'tcx> {
766755 let mut region_map = BTreeMap :: new ( ) ;
767756 let mut real_fld_r =
768757 |br : ty:: BoundRegion | * region_map. entry ( br) . or_insert_with ( || fld_r ( br) ) ;
758+ let mut fld_t = |b| bug ! ( "unexpected bound ty in binder: {b:?}" ) ;
759+ let mut fld_c = |b, ty| bug ! ( "unexpected bound ct in binder: {b:?} {ty}" ) ;
760+
769761 let value = value. skip_binder ( ) ;
770762 let value = if !value. has_escaping_bound_vars ( ) {
771763 value
772764 } else {
773- let mut replacer = BoundVarReplacer :: new ( self , Some ( & mut real_fld_r) , None , None ) ;
765+ let mut replacer = BoundVarReplacer :: new ( self , & mut real_fld_r, & mut fld_t , & mut fld_c ) ;
774766 value. fold_with ( & mut replacer)
775767 } ;
776768 ( value, region_map)
@@ -795,15 +787,14 @@ impl<'tcx> TyCtxt<'tcx> {
795787 if !value. has_escaping_bound_vars ( ) {
796788 value
797789 } else {
798- let mut replacer =
799- BoundVarReplacer :: new ( self , Some ( & mut fld_r) , Some ( & mut fld_t) , Some ( & mut fld_c) ) ;
790+ let mut replacer = BoundVarReplacer :: new ( self , & mut fld_r, & mut fld_t, & mut fld_c) ;
800791 value. fold_with ( & mut replacer)
801792 }
802793 }
803794
804795 /// Replaces all types or regions bound by the given `Binder`. The `fld_r`
805- /// closure replaces bound regions while the `fld_t` closure replaces bound
806- /// types.
796+ /// closure replaces bound regions, the `fld_t` closure replaces bound
797+ /// types, and `fld_c` replaces bound constants .
807798 pub fn replace_bound_vars < T , F , G , H > (
808799 self ,
809800 value : Binder < ' tcx , T > ,
0 commit comments