@@ -439,18 +439,18 @@ struct BoundVarReplacer<'a, 'tcx> {
439439 /// the ones we have visited.
440440 current_index : ty:: DebruijnIndex ,
441441
442- fld_r : & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) ,
443- fld_t : & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) ,
444- fld_c : & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: Const < ' tcx > + ' a ) ,
442+ fld_r : Option < & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) > ,
443+ fld_t : Option < & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) > ,
444+ fld_c : Option < & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: Const < ' tcx > + ' a ) > ,
445445}
446446
447447impl < ' a , ' tcx > BoundVarReplacer < ' a , ' tcx > {
448- fn new < F , G , H > ( tcx : TyCtxt < ' tcx > , fld_r : & ' a mut F , fld_t : & ' a mut G , fld_c : & ' a mut H ) -> Self
449- where
450- F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
451- G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx > ,
452- H : FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: Const < ' tcx > ,
453- {
448+ fn new (
449+ tcx : TyCtxt < ' tcx > ,
450+ fld_r : Option < & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) > ,
451+ fld_t : Option < & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) > ,
452+ fld_c : Option < & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: Const < ' tcx > + ' a ) > ,
453+ ) -> Self {
454454 BoundVarReplacer { tcx, current_index : ty:: INNERMOST , fld_r, fld_t, fld_c }
455455 }
456456}
@@ -469,63 +469,58 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
469469
470470 fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
471471 match * t. kind ( ) {
472- ty:: Bound ( debruijn, bound_ty) => {
473- if debruijn == self . current_index {
474- let fld_t = & mut self . fld_t ;
472+ ty:: Bound ( debruijn, bound_ty) if debruijn == self . current_index => {
473+ if let Some ( fld_t) = self . fld_t . as_mut ( ) {
475474 let ty = fld_t ( bound_ty) ;
476- ty:: fold:: shift_vars ( self . tcx , & ty, self . current_index . as_u32 ( ) )
477- } else {
478- t
475+ return ty:: fold:: shift_vars ( self . tcx , & ty, self . current_index . as_u32 ( ) ) ;
479476 }
480477 }
481- _ => {
482- if !t. has_vars_bound_at_or_above ( self . current_index ) {
483- // Nothing more to substitute.
484- t
485- } else {
486- t. super_fold_with ( self )
487- }
478+ _ if t. has_vars_bound_at_or_above ( self . current_index ) => {
479+ return t. super_fold_with ( self ) ;
488480 }
481+ _ => { }
489482 }
483+ t
490484 }
491485
492486 fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
493487 match * r {
494488 ty:: ReLateBound ( debruijn, br) if debruijn == self . current_index => {
495- let fld_r = & mut self . fld_r ;
496- let region = fld_r ( br) ;
497- if let ty:: ReLateBound ( debruijn1, br) = * region {
498- // If the callback returns a late-bound region,
499- // that region should always use the INNERMOST
500- // debruijn index. Then we adjust it to the
501- // correct depth.
502- assert_eq ! ( debruijn1, ty:: INNERMOST ) ;
503- self . tcx . mk_region ( ty:: ReLateBound ( debruijn, br) )
504- } else {
505- region
489+ if let Some ( fld_r) = self . fld_r . as_mut ( ) {
490+ let region = fld_r ( br) ;
491+ return if let ty:: ReLateBound ( debruijn1, br) = * region {
492+ // If the callback returns a late-bound region,
493+ // that region should always use the INNERMOST
494+ // debruijn index. Then we adjust it to the
495+ // correct depth.
496+ assert_eq ! ( debruijn1, ty:: INNERMOST ) ;
497+ self . tcx . mk_region ( ty:: ReLateBound ( debruijn, br) )
498+ } else {
499+ region
500+ } ;
506501 }
507502 }
508- _ => r ,
503+ _ => { }
509504 }
505+ r
510506 }
511507
512508 fn fold_const ( & mut self , ct : & ' tcx ty:: Const < ' tcx > ) -> & ' tcx ty:: Const < ' tcx > {
513- if let ty:: Const { val : ty:: ConstKind :: Bound ( debruijn, bound_const) , ty } = * ct {
514- if debruijn == self . current_index {
515- let fld_c = & mut self . fld_c ;
516- let ct = fld_c ( bound_const, ty) ;
517- ty:: fold:: shift_vars ( self . tcx , & ct, self . current_index . as_u32 ( ) )
518- } else {
519- ct
509+ match * ct {
510+ ty:: Const { val : ty:: ConstKind :: Bound ( debruijn, bound_const) , ty }
511+ if debruijn == self . current_index =>
512+ {
513+ if let Some ( fld_c) = self . fld_c . as_mut ( ) {
514+ let ct = fld_c ( bound_const, ty) ;
515+ return ty:: fold:: shift_vars ( self . tcx , & ct, self . current_index . as_u32 ( ) ) ;
516+ }
520517 }
521- } else {
522- if !ct. has_vars_bound_at_or_above ( self . current_index ) {
523- // Nothing more to substitute.
524- ct
525- } else {
526- ct. super_fold_with ( self )
518+ _ if ct. has_vars_bound_at_or_above ( self . current_index ) => {
519+ return ct. super_fold_with ( self ) ;
527520 }
521+ _ => { }
528522 }
523+ ct
529524 }
530525}
531526
@@ -550,14 +545,16 @@ impl<'tcx> TyCtxt<'tcx> {
550545 F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
551546 T : TypeFoldable < ' tcx > ,
552547 {
553- // identity for bound types and consts
554- let fld_t = |bound_ty| self . mk_ty ( ty:: Bound ( ty:: INNERMOST , bound_ty) ) ;
555- let fld_c = |bound_ct, ty| {
556- self . mk_const ( ty:: Const { val : ty:: ConstKind :: Bound ( ty:: INNERMOST , bound_ct) , ty } )
557- } ;
558548 let mut region_map = BTreeMap :: new ( ) ;
559- let real_fld_r = |br : ty:: BoundRegion | * region_map. entry ( br) . or_insert_with ( || fld_r ( br) ) ;
560- let value = self . replace_escaping_bound_vars ( value. skip_binder ( ) , real_fld_r, fld_t, fld_c) ;
549+ let mut real_fld_r =
550+ |br : ty:: BoundRegion | * region_map. entry ( br) . or_insert_with ( || fld_r ( br) ) ;
551+ let value = value. skip_binder ( ) ;
552+ let value = if !value. has_escaping_bound_vars ( ) {
553+ value
554+ } else {
555+ let mut replacer = BoundVarReplacer :: new ( self , Some ( & mut real_fld_r) , None , None ) ;
556+ value. fold_with ( & mut replacer)
557+ } ;
561558 ( value, region_map)
562559 }
563560
@@ -580,7 +577,8 @@ impl<'tcx> TyCtxt<'tcx> {
580577 if !value. has_escaping_bound_vars ( ) {
581578 value
582579 } else {
583- let mut replacer = BoundVarReplacer :: new ( self , & mut fld_r, & mut fld_t, & mut fld_c) ;
580+ let mut replacer =
581+ BoundVarReplacer :: new ( self , Some ( & mut fld_r) , Some ( & mut fld_t) , Some ( & mut fld_c) ) ;
584582 value. fold_with ( & mut replacer)
585583 }
586584 }
0 commit comments