@@ -431,22 +431,26 @@ struct BoundVarReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
431431
432432 fld_r : & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) ,
433433 fld_t : & ' a mut ( dyn FnMut ( ty:: BoundTy ) -> Ty < ' tcx > + ' a ) ,
434+ fld_c : & ' a mut ( dyn FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > + ' a ) ,
434435}
435436
436437impl < ' a , ' gcx , ' tcx > BoundVarReplacer < ' a , ' gcx , ' tcx > {
437- fn new < F , G > (
438+ fn new < F , G , H > (
438439 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
439440 fld_r : & ' a mut F ,
440- fld_t : & ' a mut G
441+ fld_t : & ' a mut G ,
442+ fld_c : & ' a mut H ,
441443 ) -> Self
442444 where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
443- G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx >
445+ G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx > ,
446+ H : FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > ,
444447 {
445448 BoundVarReplacer {
446449 tcx,
447450 current_index : ty:: INNERMOST ,
448451 fld_r,
449452 fld_t,
453+ fld_c,
450454 }
451455 }
452456}
@@ -508,7 +512,29 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx>
508512 }
509513
510514 fn fold_const ( & mut self , ct : & ' tcx ty:: LazyConst < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > {
511- ct // FIXME(const_generics)
515+ if let ty:: LazyConst :: Evaluated ( ty:: Const {
516+ val : ConstValue :: Infer ( ty:: InferConst :: Canonical ( debruijn, bound_const) ) ,
517+ ty,
518+ } ) = * ct {
519+ if debruijn == self . current_index {
520+ let fld_c = & mut self . fld_c ;
521+ let ct = fld_c ( bound_const, ty) ;
522+ ty:: fold:: shift_vars (
523+ self . tcx ,
524+ & ct,
525+ self . current_index . as_u32 ( )
526+ )
527+ } else {
528+ ct
529+ }
530+ } else {
531+ if !ct. has_vars_bound_at_or_above ( self . current_index ) {
532+ // Nothing more to substitute.
533+ ct
534+ } else {
535+ ct. super_fold_with ( self )
536+ }
537+ }
512538 }
513539}
514540
@@ -532,27 +558,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
532558 where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
533559 T : TypeFoldable < ' tcx >
534560 {
535- // identity for bound types
561+ // identity for bound types and consts
536562 let fld_t = |bound_ty| self . mk_ty ( ty:: Bound ( ty:: INNERMOST , bound_ty) ) ;
537- self . replace_escaping_bound_vars ( value. skip_binder ( ) , fld_r, fld_t)
563+ let fld_c = |bound_ct, ty| {
564+ self . mk_const_infer ( ty:: InferConst :: Canonical ( ty:: INNERMOST , bound_ct) , ty)
565+ } ;
566+ self . replace_escaping_bound_vars ( value. skip_binder ( ) , fld_r, fld_t, fld_c)
538567 }
539568
540569 /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping
541- /// bound regions while the `fld_t` closure replaces escaping bound types.
542- pub fn replace_escaping_bound_vars < T , F , G > (
570+ /// bound regions; the `fld_t` closure replaces escaping bound types and the `fld_c`
571+ /// closure replaces escaping bound consts.
572+ pub fn replace_escaping_bound_vars < T , F , G , H > (
543573 self ,
544574 value : & T ,
545575 mut fld_r : F ,
546- mut fld_t : G
576+ mut fld_t : G ,
577+ mut fld_c : H ,
547578 ) -> ( T , BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > )
548579 where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
549580 G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx > ,
550- T : TypeFoldable < ' tcx >
581+ H : FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > ,
582+ T : TypeFoldable < ' tcx > ,
551583 {
552584 use rustc_data_structures:: fx:: FxHashMap ;
553585
554586 let mut region_map = BTreeMap :: new ( ) ;
555587 let mut type_map = FxHashMap :: default ( ) ;
588+ let mut const_map = FxHashMap :: default ( ) ;
556589
557590 if !value. has_escaping_bound_vars ( ) {
558591 ( value. clone ( ) , region_map)
@@ -565,7 +598,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
565598 * type_map. entry ( bound_ty) . or_insert_with ( || fld_t ( bound_ty) )
566599 } ;
567600
568- let mut replacer = BoundVarReplacer :: new ( self , & mut real_fld_r, & mut real_fld_t) ;
601+ let mut real_fld_c = |bound_ct, ty| {
602+ * const_map. entry ( bound_ct) . or_insert_with ( || fld_c ( bound_ct, ty) )
603+ } ;
604+
605+ let mut replacer = BoundVarReplacer :: new (
606+ self ,
607+ & mut real_fld_r,
608+ & mut real_fld_t,
609+ & mut real_fld_c,
610+ ) ;
569611 let result = value. fold_with ( & mut replacer) ;
570612 ( result, region_map)
571613 }
@@ -574,17 +616,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
574616 /// Replaces all types or regions bound by the given `Binder`. The `fld_r`
575617 /// closure replaces bound regions while the `fld_t` closure replaces bound
576618 /// types.
577- pub fn replace_bound_vars < T , F , G > (
619+ pub fn replace_bound_vars < T , F , G , H > (
578620 self ,
579621 value : & Binder < T > ,
580622 fld_r : F ,
581- fld_t : G
623+ fld_t : G ,
624+ fld_c : H ,
582625 ) -> ( T , BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > )
583626 where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
584627 G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx > ,
628+ H : FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > ,
585629 T : TypeFoldable < ' tcx >
586630 {
587- self . replace_escaping_bound_vars ( value. skip_binder ( ) , fld_r, fld_t)
631+ self . replace_escaping_bound_vars ( value. skip_binder ( ) , fld_r, fld_t, fld_c )
588632 }
589633
590634 /// Replaces any late-bound regions bound in `value` with
0 commit comments