@@ -37,7 +37,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
37
37
pub tcx : TyCtxtAt < ' tcx > ,
38
38
39
39
/// 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 > > ,
41
43
42
44
/// The virtual memory system.
43
45
pub memory : Memory < ' mir , ' tcx , M > ,
@@ -298,7 +300,7 @@ where
298
300
M : Machine < ' mir , ' tcx > ,
299
301
{
300
302
fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > {
301
- self . param_env
303
+ self . param_env . get ( )
302
304
}
303
305
}
304
306
@@ -405,7 +407,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
405
407
InterpCx {
406
408
machine,
407
409
tcx : tcx. at ( root_span) ,
408
- param_env,
410
+ param_env : Cell :: new ( param_env ) ,
409
411
memory : Memory :: new ( ) ,
410
412
recursion_limit : tcx. recursion_limit ( ) ,
411
413
}
@@ -418,6 +420,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
418
420
self . stack ( ) . last ( ) . map_or ( self . tcx . span , |f| f. current_span ( ) )
419
421
}
420
422
423
+ #[ inline( always) ]
424
+ pub fn param_env ( & self ) -> ParamEnv < ' tcx > {
425
+ self . param_env . get ( )
426
+ }
427
+
421
428
#[ inline( always) ]
422
429
pub ( crate ) fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: Provenance , M :: FrameExtra > ] {
423
430
M :: stack ( self )
@@ -465,7 +472,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
465
472
466
473
#[ inline]
467
474
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
469
482
}
470
483
471
484
pub fn load_mir (
@@ -505,7 +518,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
505
518
) -> Result < T , InterpError < ' tcx > > {
506
519
frame
507
520
. 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
+ } )
509
528
. map_err ( |e| {
510
529
self . tcx . sess . delay_span_bug (
511
530
self . cur_span ( ) ,
@@ -517,15 +536,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
517
536
}
518
537
519
538
/// 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) ]
520
540
pub ( super ) fn resolve (
521
541
& self ,
522
542
def : ty:: WithOptConstParam < DefId > ,
523
543
substs : SubstsRef < ' tcx > ,
524
544
) -> 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) {
529
546
Ok ( Some ( instance) ) => Ok ( instance) ,
530
547
Ok ( None ) => throw_inval ! ( TooGeneric ) ,
531
548
@@ -545,7 +562,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
545
562
// have to support that case (mostly by skipping all caching).
546
563
match frame. locals . get ( local) . and_then ( |state| state. layout . get ( ) ) {
547
564
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, || {
549
566
let local_ty = frame. body . local_decls [ local] . ty ;
550
567
let local_ty =
551
568
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> {
914
931
let param_env = if self . tcx . is_static ( gid. instance . def_id ( ) ) {
915
932
ty:: ParamEnv :: reveal_all ( )
916
933
} else {
917
- self . param_env
934
+ self . param_env ( )
918
935
} ;
919
936
let param_env = param_env. with_const ( ) ;
920
937
// Use a precise span for better cycle errors.
0 commit comments