@@ -656,17 +656,17 @@ struct BoundVarReplacer<'a, 'tcx> {
656
656
/// the ones we have visited.
657
657
current_index : ty:: DebruijnIndex ,
658
658
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 ) ,
662
662
}
663
663
664
664
impl < ' a , ' tcx > BoundVarReplacer < ' a , ' tcx > {
665
665
fn new (
666
666
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 ) ,
670
670
) -> Self {
671
671
BoundVarReplacer { tcx, current_index : ty:: INNERMOST , fld_r, fld_t, fld_c }
672
672
}
@@ -690,55 +690,42 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
690
690
fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
691
691
match * t. kind ( ) {
692
692
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 ( ) )
700
695
}
701
- _ => { }
696
+ _ if t. has_vars_bound_at_or_above ( self . current_index ) => t. super_fold_with ( self ) ,
697
+ _ => t,
702
698
}
703
- t
704
699
}
705
700
706
701
fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
707
702
match * r {
708
703
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
721
714
}
722
715
}
723
- _ => { }
716
+ _ => r ,
724
717
}
725
- r
726
718
}
727
719
728
720
fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
729
721
match ct. val ( ) {
730
722
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 ( ) )
738
725
}
739
- _ => { }
726
+ _ if ct. has_vars_bound_at_or_above ( self . current_index ) => ct. super_fold_with ( self ) ,
727
+ _ => ct,
740
728
}
741
- ct
742
729
}
743
730
}
744
731
@@ -752,8 +739,10 @@ impl<'tcx> TyCtxt<'tcx> {
752
739
/// returned at the end with each bound region and the free region
753
740
/// that replaced it.
754
741
///
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.
757
746
pub fn replace_late_bound_regions < T , F > (
758
747
self ,
759
748
value : Binder < ' tcx , T > ,
@@ -766,11 +755,14 @@ impl<'tcx> TyCtxt<'tcx> {
766
755
let mut region_map = BTreeMap :: new ( ) ;
767
756
let mut real_fld_r =
768
757
|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
+
769
761
let value = value. skip_binder ( ) ;
770
762
let value = if !value. has_escaping_bound_vars ( ) {
771
763
value
772
764
} 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 ) ;
774
766
value. fold_with ( & mut replacer)
775
767
} ;
776
768
( value, region_map)
@@ -795,15 +787,14 @@ impl<'tcx> TyCtxt<'tcx> {
795
787
if !value. has_escaping_bound_vars ( ) {
796
788
value
797
789
} 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) ;
800
791
value. fold_with ( & mut replacer)
801
792
}
802
793
}
803
794
804
795
/// 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 .
807
798
pub fn replace_bound_vars < T , F , G , H > (
808
799
self ,
809
800
value : Binder < ' tcx , T > ,
0 commit comments