@@ -439,18 +439,18 @@ struct BoundVarReplacer<'a, 'tcx> {
439
439
/// the ones we have visited.
440
440
current_index : ty:: DebruijnIndex ,
441
441
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 ) > ,
445
445
}
446
446
447
447
impl < ' 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 {
454
454
BoundVarReplacer { tcx, current_index : ty:: INNERMOST , fld_r, fld_t, fld_c }
455
455
}
456
456
}
@@ -469,63 +469,58 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
469
469
470
470
fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
471
471
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 ( ) {
475
474
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 ( ) ) ;
479
476
}
480
477
}
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 ) ;
488
480
}
481
+ _ => { }
489
482
}
483
+ t
490
484
}
491
485
492
486
fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
493
487
match * r {
494
488
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
+ } ;
506
501
}
507
502
}
508
- _ => r ,
503
+ _ => { }
509
504
}
505
+ r
510
506
}
511
507
512
508
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
+ }
520
517
}
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 ) ;
527
520
}
521
+ _ => { }
528
522
}
523
+ ct
529
524
}
530
525
}
531
526
@@ -550,14 +545,16 @@ impl<'tcx> TyCtxt<'tcx> {
550
545
F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
551
546
T : TypeFoldable < ' tcx > ,
552
547
{
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
- } ;
558
548
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
+ } ;
561
558
( value, region_map)
562
559
}
563
560
@@ -580,7 +577,8 @@ impl<'tcx> TyCtxt<'tcx> {
580
577
if !value. has_escaping_bound_vars ( ) {
581
578
value
582
579
} 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) ) ;
584
582
value. fold_with ( & mut replacer)
585
583
}
586
584
}
0 commit comments