@@ -635,13 +635,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
635635
636636    #[ instrument( skip( self ) ,  level = "debug" ) ]  
637637    fn  fold_const ( & mut  self ,  constant :  ty:: Const < ' tcx > )  -> ty:: Const < ' tcx >  { 
638-         if  self . selcx . tcx ( ) . lazy_normalization ( )  || !self . eager_inference_replacement  { 
638+         let  tcx = self . selcx . tcx ( ) ; 
639+         if  tcx. lazy_normalization ( )  { 
639640            constant
640641        }  else  { 
641642            let  constant = constant. super_fold_with ( self ) ; 
642-             debug ! ( ?constant) ; 
643-             debug ! ( "self.param_env: {:?}" ,  self . param_env) ; 
644-             constant. eval ( self . selcx . tcx ( ) ,  self . param_env ) 
643+             debug ! ( ?constant,  ?self . param_env) ; 
644+             with_replaced_escaping_bound_vars ( 
645+                 self . selcx . infcx ( ) , 
646+                 & mut  self . universes , 
647+                 constant, 
648+                 |constant| constant. eval ( tcx,  self . param_env ) , 
649+             ) 
645650        } 
646651    } 
647652
@@ -671,6 +676,41 @@ pub struct BoundVarReplacer<'me, 'tcx> {
671676    universe_indices :  & ' me  mut  Vec < Option < ty:: UniverseIndex > > , 
672677} 
673678
679+ /// Executes `f` on `value` after replacing all escaping bound variables with placeholders 
680+ /// and then replaces these placeholders with the original bound variables in the result. 
681+ /// 
682+ /// In most places, bound variables should be replaced right when entering a binder, making 
683+ /// this function unnecessary. However, normalization currently does not do that, so we have 
684+ /// to do this lazily. 
685+ /// 
686+ /// You should not add any additional uses of this function, at least not without first 
687+ /// discussing it with t-types. 
688+ /// 
689+ /// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during 
690+ /// normalization as well, at which point this function will be unnecessary and can be removed. 
691+ pub  fn  with_replaced_escaping_bound_vars < ' a ,  ' tcx ,  T :  TypeFoldable < ' tcx > ,  R :  TypeFoldable < ' tcx > > ( 
692+     infcx :  & ' a  InferCtxt < ' a ,  ' tcx > , 
693+     universe_indices :  & ' a  mut  Vec < Option < ty:: UniverseIndex > > , 
694+     value :  T , 
695+     f :  impl  FnOnce ( T )  -> R , 
696+ )  -> R  { 
697+     if  value. has_escaping_bound_vars ( )  { 
698+         let  ( value,  mapped_regions,  mapped_types,  mapped_consts)  =
699+             BoundVarReplacer :: replace_bound_vars ( infcx,  universe_indices,  value) ; 
700+         let  result = f ( value) ; 
701+         PlaceholderReplacer :: replace_placeholders ( 
702+             infcx, 
703+             mapped_regions, 
704+             mapped_types, 
705+             mapped_consts, 
706+             universe_indices, 
707+             result, 
708+         ) 
709+     }  else  { 
710+         f ( value) 
711+     } 
712+ } 
713+ 
674714impl < ' me ,  ' tcx >  BoundVarReplacer < ' me ,  ' tcx >  { 
675715    /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that 
676716     /// use a binding level above `universe_indices.len()`, we fail. 
0 commit comments