@@ -431,22 +431,26 @@ struct BoundVarReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
431
431
432
432
fld_r : & ' a mut ( dyn FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > + ' a ) ,
433
433
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 ) ,
434
435
}
435
436
436
437
impl < ' a , ' gcx , ' tcx > BoundVarReplacer < ' a , ' gcx , ' tcx > {
437
- fn new < F , G > (
438
+ fn new < F , G , H > (
438
439
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
439
440
fld_r : & ' a mut F ,
440
- fld_t : & ' a mut G
441
+ fld_t : & ' a mut G ,
442
+ fld_c : & ' a mut H ,
441
443
) -> Self
442
444
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 > ,
444
447
{
445
448
BoundVarReplacer {
446
449
tcx,
447
450
current_index : ty:: INNERMOST ,
448
451
fld_r,
449
452
fld_t,
453
+ fld_c,
450
454
}
451
455
}
452
456
}
@@ -508,7 +512,29 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx>
508
512
}
509
513
510
514
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
+ }
512
538
}
513
539
}
514
540
@@ -532,27 +558,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
532
558
where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
533
559
T : TypeFoldable < ' tcx >
534
560
{
535
- // identity for bound types
561
+ // identity for bound types and consts
536
562
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)
538
567
}
539
568
540
569
/// 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 > (
543
573
self ,
544
574
value : & T ,
545
575
mut fld_r : F ,
546
- mut fld_t : G
576
+ mut fld_t : G ,
577
+ mut fld_c : H ,
547
578
) -> ( T , BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > )
548
579
where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
549
580
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 > ,
551
583
{
552
584
use rustc_data_structures:: fx:: FxHashMap ;
553
585
554
586
let mut region_map = BTreeMap :: new ( ) ;
555
587
let mut type_map = FxHashMap :: default ( ) ;
588
+ let mut const_map = FxHashMap :: default ( ) ;
556
589
557
590
if !value. has_escaping_bound_vars ( ) {
558
591
( value. clone ( ) , region_map)
@@ -565,7 +598,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
565
598
* type_map. entry ( bound_ty) . or_insert_with ( || fld_t ( bound_ty) )
566
599
} ;
567
600
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
+ ) ;
569
611
let result = value. fold_with ( & mut replacer) ;
570
612
( result, region_map)
571
613
}
@@ -574,17 +616,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
574
616
/// Replaces all types or regions bound by the given `Binder`. The `fld_r`
575
617
/// closure replaces bound regions while the `fld_t` closure replaces bound
576
618
/// types.
577
- pub fn replace_bound_vars < T , F , G > (
619
+ pub fn replace_bound_vars < T , F , G , H > (
578
620
self ,
579
621
value : & Binder < T > ,
580
622
fld_r : F ,
581
- fld_t : G
623
+ fld_t : G ,
624
+ fld_c : H ,
582
625
) -> ( T , BTreeMap < ty:: BoundRegion , ty:: Region < ' tcx > > )
583
626
where F : FnMut ( ty:: BoundRegion ) -> ty:: Region < ' tcx > ,
584
627
G : FnMut ( ty:: BoundTy ) -> Ty < ' tcx > ,
628
+ H : FnMut ( ty:: BoundVar , Ty < ' tcx > ) -> & ' tcx ty:: LazyConst < ' tcx > ,
585
629
T : TypeFoldable < ' tcx >
586
630
{
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 )
588
632
}
589
633
590
634
/// Replaces any late-bound regions bound in `value` with
0 commit comments