@@ -37,7 +37,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
3737 pub tcx : TyCtxtAt < ' tcx > ,
3838
3939 /// Bounds in scope for polymorphic evaluations.
40- pub ( crate ) param_env : ty:: ParamEnv < ' tcx > ,
40+ ///
41+ /// This has to be mutable as we may only lazily reveal opaque types.
42+ pub ( crate ) param_env : Cell < ty:: ParamEnv < ' tcx > > ,
4143
4244 /// The virtual memory system.
4345 pub memory : Memory < ' mir , ' tcx , M > ,
@@ -298,7 +300,7 @@ where
298300 M : Machine < ' mir , ' tcx > ,
299301{
300302 fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
301- self . param_env
303+ self . param_env . get ( )
302304 }
303305}
304306
@@ -405,7 +407,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
405407 InterpCx {
406408 machine,
407409 tcx : tcx. at ( root_span) ,
408- param_env,
410+ param_env : Cell :: new ( param_env ) ,
409411 memory : Memory :: new ( ) ,
410412 recursion_limit : tcx. recursion_limit ( ) ,
411413 }
@@ -418,6 +420,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
418420 self . stack ( ) . last ( ) . map_or ( self . tcx . span , |f| f. current_span ( ) )
419421 }
420422
423+ #[ inline( always) ]
424+ pub fn param_env ( & self ) -> ParamEnv < ' tcx > {
425+ self . param_env . get ( )
426+ }
427+
421428 #[ inline( always) ]
422429 pub ( crate ) fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: Provenance , M :: FrameExtra > ] {
423430 M :: stack ( self )
@@ -465,7 +472,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
465472
466473 #[ inline]
467474 pub fn type_is_freeze ( & self , ty : Ty < ' tcx > ) -> bool {
468- ty. is_freeze ( self . tcx , self . param_env )
475+ ty. is_freeze ( self . tcx , self . param_env ( ) )
476+ }
477+
478+ pub fn reveal_opaque_types_in_value < T : TypeFoldable < ' tcx > > ( & self , value : T ) -> T {
479+ let ( param_env, value) = self . tcx . reveal_opaque_types_in_value ( self . param_env . get ( ) , value) ;
480+ self . param_env . set ( param_env) ;
481+ value
469482 }
470483
471484 pub fn load_mir (
@@ -505,7 +518,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
505518 ) -> Result < T , InterpError < ' tcx > > {
506519 frame
507520 . instance
508- . try_subst_mir_and_normalize_erasing_regions ( * self . tcx , self . param_env , value)
521+ . try_subst_mir_and_normalize_erasing_regions ( * self . tcx , self . param_env ( ) , value)
522+ . map ( |value| {
523+ let ( param_env, value) =
524+ self . tcx . reveal_opaque_types_in_value ( self . param_env . get ( ) , value) ;
525+ self . param_env . set ( param_env) ;
526+ value
527+ } )
509528 . map_err ( |e| {
510529 self . tcx . sess . delay_span_bug (
511530 self . cur_span ( ) ,
@@ -517,15 +536,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
517536 }
518537
519538 /// The `substs` are assumed to already be in our interpreter "universe" (param_env).
539+ #[ instrument( level = "trace" , skip( self ) , fields( param_env = ?self . param_env) , ret) ]
520540 pub ( super ) fn resolve (
521541 & self ,
522542 def : ty:: WithOptConstParam < DefId > ,
523543 substs : SubstsRef < ' tcx > ,
524544 ) -> InterpResult < ' tcx , ty:: Instance < ' tcx > > {
525- trace ! ( "resolve: {:?}, {:#?}" , def, substs) ;
526- trace ! ( "param_env: {:#?}" , self . param_env) ;
527- trace ! ( "substs: {:#?}" , substs) ;
528- match ty:: Instance :: resolve_opt_const_arg ( * self . tcx , self . param_env , def, substs) {
545+ match ty:: Instance :: resolve_opt_const_arg ( * self . tcx , self . param_env ( ) , def, substs) {
529546 Ok ( Some ( instance) ) => Ok ( instance) ,
530547 Ok ( None ) => throw_inval ! ( TooGeneric ) ,
531548
@@ -545,7 +562,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
545562 // have to support that case (mostly by skipping all caching).
546563 match frame. locals . get ( local) . and_then ( |state| state. layout . get ( ) ) {
547564 None => {
548- let layout = from_known_layout ( self . tcx , self . param_env , layout, || {
565+ let layout = from_known_layout ( self . tcx , self . param_env ( ) , layout, || {
549566 let local_ty = frame. body . local_decls [ local] . ty ;
550567 let local_ty =
551568 self . subst_from_frame_and_normalize_erasing_regions ( frame, local_ty) ?;
@@ -914,7 +931,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
914931 let param_env = if self . tcx . is_static ( gid. instance . def_id ( ) ) {
915932 ty:: ParamEnv :: reveal_all ( )
916933 } else {
917- self . param_env
934+ self . param_env ( )
918935 } ;
919936 let param_env = param_env. with_const ( ) ;
920937 // Use a precise span for better cycle errors.
0 commit comments