@@ -20,11 +20,32 @@ use rustc_const_math::ConstInt;
2020use std:: fmt;
2121use std:: error:: Error ;
2222
23+
24+ pub fn mk_eval_cx < ' a , ' tcx > (
25+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
26+ instance : Instance < ' tcx > ,
27+ param_env : ty:: ParamEnv < ' tcx > ,
28+ ) -> EvalResult < ' tcx , EvalContext < ' a , ' tcx , CompileTimeEvaluator > > {
29+ debug ! ( "mk_eval_cx: {:?}, {:?}" , instance, param_env) ;
30+ let limits = super :: ResourceLimits :: default ( ) ;
31+ let mut ecx = EvalContext :: new ( tcx, param_env, limits, CompileTimeEvaluator , ( ) ) ;
32+ let mir = ecx. load_mir ( instance. def ) ?;
33+ // insert a stack frame so any queries have the correct substs
34+ ecx. push_stack_frame (
35+ instance,
36+ mir. span ,
37+ mir,
38+ Place :: undef ( ) ,
39+ StackPopCleanup :: None ,
40+ ) ?;
41+ Ok ( ecx)
42+ }
43+
2344pub fn eval_body < ' a , ' tcx > (
2445 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
2546 instance : Instance < ' tcx > ,
2647 param_env : ty:: ParamEnv < ' tcx > ,
27- ) -> ( EvalResult < ' tcx , ( PtrAndAlign , Ty < ' tcx > ) > , EvalContext < ' a , ' tcx , CompileTimeEvaluator > ) {
48+ ) -> EvalResult < ' tcx , ( PtrAndAlign , Ty < ' tcx > ) > {
2849 debug ! ( "eval_body: {:?}, {:?}" , instance, param_env) ;
2950 let limits = super :: ResourceLimits :: default ( ) ;
3051 let mut ecx = EvalContext :: new ( tcx, param_env, limits, CompileTimeEvaluator , ( ) ) ;
@@ -33,64 +54,53 @@ pub fn eval_body<'a, 'tcx>(
3354 promoted : None ,
3455 } ;
3556
36- let try = ( || {
37- if ecx. tcx . has_attr ( instance. def_id ( ) , "linkage" ) {
38- return Err ( ConstEvalError :: NotConst ( "extern global" . to_string ( ) ) . into ( ) ) ;
39- }
40- // FIXME(eddyb) use `Instance::ty` when it becomes available.
41- let instance_ty =
42- ecx. monomorphize ( instance. def . def_ty ( tcx) , instance. substs ) ;
43- if tcx. interpret_interner . borrow ( ) . get_cached ( cid) . is_none ( ) {
44- let mir = ecx. load_mir ( instance. def ) ?;
45- let layout = ecx. layout_of ( instance_ty) ?;
46- assert ! ( !layout. is_unsized( ) ) ;
47- let ptr = ecx. memory . allocate (
48- layout. size . bytes ( ) ,
49- layout. align . abi ( ) ,
50- None ,
51- ) ?;
52- tcx. interpret_interner . borrow_mut ( ) . cache (
53- cid,
54- PtrAndAlign {
55- ptr : ptr. into ( ) ,
56- aligned : !layout. is_packed ( ) ,
57- } ,
58- ) ;
59- let cleanup = StackPopCleanup :: MarkStatic ( Mutability :: Immutable ) ;
60- let name = ty:: tls:: with ( |tcx| tcx. item_path_str ( instance. def_id ( ) ) ) ;
61- trace ! ( "const_eval: pushing stack frame for global: {}" , name) ;
62- ecx. push_stack_frame (
63- instance,
64- mir. span ,
65- mir,
66- Place :: from_ptr ( ptr) ,
67- cleanup. clone ( ) ,
68- ) ?;
69-
70- while ecx. step ( ) ? { }
71-
72- // reinsert the stack frame so any future queries have the correct substs
73- ecx. push_stack_frame (
74- instance,
75- mir. span ,
76- mir,
77- Place :: from_ptr ( ptr) ,
78- cleanup,
79- ) ?;
80- }
81- let value = tcx. interpret_interner . borrow ( ) . get_cached ( cid) . expect ( "global not cached" ) ;
82- Ok ( ( value, instance_ty) )
83- } ) ( ) ;
84- ( try, ecx)
57+ if ecx. tcx . has_attr ( instance. def_id ( ) , "linkage" ) {
58+ return Err ( ConstEvalError :: NotConst ( "extern global" . to_string ( ) ) . into ( ) ) ;
59+ }
60+ // FIXME(eddyb) use `Instance::ty` when it becomes available.
61+ let instance_ty =
62+ ecx. monomorphize ( instance. def . def_ty ( tcx) , instance. substs ) ;
63+ if tcx. interpret_interner . borrow ( ) . get_cached ( cid) . is_none ( ) {
64+ let mir = ecx. load_mir ( instance. def ) ?;
65+ let layout = ecx. layout_of ( instance_ty) ?;
66+ assert ! ( !layout. is_unsized( ) ) ;
67+ let ptr = ecx. memory . allocate (
68+ layout. size . bytes ( ) ,
69+ layout. align . abi ( ) ,
70+ None ,
71+ ) ?;
72+ tcx. interpret_interner . borrow_mut ( ) . cache (
73+ cid,
74+ PtrAndAlign {
75+ ptr : ptr. into ( ) ,
76+ aligned : !layout. is_packed ( ) ,
77+ } ,
78+ ) ;
79+ let cleanup = StackPopCleanup :: MarkStatic ( Mutability :: Immutable ) ;
80+ let name = ty:: tls:: with ( |tcx| tcx. item_path_str ( instance. def_id ( ) ) ) ;
81+ trace ! ( "const_eval: pushing stack frame for global: {}" , name) ;
82+ ecx. push_stack_frame (
83+ instance,
84+ mir. span ,
85+ mir,
86+ Place :: from_ptr ( ptr) ,
87+ cleanup. clone ( ) ,
88+ ) ?;
89+
90+ while ecx. step ( ) ? { }
91+ }
92+ let value = tcx. interpret_interner . borrow ( ) . get_cached ( cid) . expect ( "global not cached" ) ;
93+ Ok ( ( value, instance_ty) )
8594}
8695
8796pub fn eval_body_as_integer < ' a , ' tcx > (
8897 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
8998 param_env : ty:: ParamEnv < ' tcx > ,
9099 instance : Instance < ' tcx > ,
91100) -> EvalResult < ' tcx , ConstInt > {
92- let ( ptr_ty, ecx ) = eval_body ( tcx, instance, param_env) ;
101+ let ptr_ty = eval_body ( tcx, instance, param_env) ;
93102 let ( ptr, ty) = ptr_ty?;
103+ let ecx = mk_eval_cx ( tcx, instance, param_env) ?;
94104 let prim = match ecx. read_maybe_aligned ( ptr. aligned , |ectx| ectx. try_read_value ( ptr. ptr , ty) ) ? {
95105 Some ( Value :: ByVal ( prim) ) => prim. to_bytes ( ) ?,
96106 _ => return err ! ( TypeNotPrimitive ( ty) ) ,
@@ -340,20 +350,19 @@ pub fn const_eval_provider<'a, 'tcx>(
340350 trace ! ( "const eval instance: {:?}, {:?}" , instance, key. param_env) ;
341351 let miri_result = :: interpret:: eval_body ( tcx, instance, key. param_env ) ;
342352 match ( miri_result, old_result) {
343- ( ( Err ( err) , ecx ) , Ok ( ok) ) => {
353+ ( Err ( err) , Ok ( ok) ) => {
344354 trace ! ( "miri failed, ctfe returned {:?}" , ok) ;
345355 tcx. sess . span_warn (
346356 tcx. def_span ( key. value . 0 ) ,
347357 "miri failed to eval, while ctfe succeeded" ,
348358 ) ;
359+ let ecx = mk_eval_cx ( tcx, instance, key. param_env ) . unwrap ( ) ;
349360 let ( ) = unwrap_miri ( & ecx, Err ( err) ) ;
350361 Ok ( ok)
351362 } ,
352- ( ( Ok ( _) , _) , Err ( err) ) => {
353- Err ( err)
354- } ,
355- ( ( Err ( _) , _) , Err ( err) ) => Err ( err) ,
356- ( ( Ok ( ( miri_val, miri_ty) ) , mut ecx) , Ok ( ctfe) ) => {
363+ ( _, Err ( err) ) => Err ( err) ,
364+ ( Ok ( ( miri_val, miri_ty) ) , Ok ( ctfe) ) => {
365+ let mut ecx = mk_eval_cx ( tcx, instance, key. param_env ) . unwrap ( ) ;
357366 check_ctfe_against_miri ( & mut ecx, miri_val, miri_ty, ctfe. val ) ;
358367 Ok ( ctfe)
359368 }
0 commit comments