@@ -20,11 +20,32 @@ use rustc_const_math::ConstInt;
20
20
use std:: fmt;
21
21
use std:: error:: Error ;
22
22
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
+
23
44
pub fn eval_body < ' a , ' tcx > (
24
45
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
25
46
instance : Instance < ' tcx > ,
26
47
param_env : ty:: ParamEnv < ' tcx > ,
27
- ) -> ( EvalResult < ' tcx , ( PtrAndAlign , Ty < ' tcx > ) > , EvalContext < ' a , ' tcx , CompileTimeEvaluator > ) {
48
+ ) -> EvalResult < ' tcx , ( PtrAndAlign , Ty < ' tcx > ) > {
28
49
debug ! ( "eval_body: {:?}, {:?}" , instance, param_env) ;
29
50
let limits = super :: ResourceLimits :: default ( ) ;
30
51
let mut ecx = EvalContext :: new ( tcx, param_env, limits, CompileTimeEvaluator , ( ) ) ;
@@ -33,64 +54,53 @@ pub fn eval_body<'a, 'tcx>(
33
54
promoted : None ,
34
55
} ;
35
56
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) )
85
94
}
86
95
87
96
pub fn eval_body_as_integer < ' a , ' tcx > (
88
97
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
89
98
param_env : ty:: ParamEnv < ' tcx > ,
90
99
instance : Instance < ' tcx > ,
91
100
) -> EvalResult < ' tcx , ConstInt > {
92
- let ( ptr_ty, ecx ) = eval_body ( tcx, instance, param_env) ;
101
+ let ptr_ty = eval_body ( tcx, instance, param_env) ;
93
102
let ( ptr, ty) = ptr_ty?;
103
+ let ecx = mk_eval_cx ( tcx, instance, param_env) ?;
94
104
let prim = match ecx. read_maybe_aligned ( ptr. aligned , |ectx| ectx. try_read_value ( ptr. ptr , ty) ) ? {
95
105
Some ( Value :: ByVal ( prim) ) => prim. to_bytes ( ) ?,
96
106
_ => return err ! ( TypeNotPrimitive ( ty) ) ,
@@ -340,20 +350,19 @@ pub fn const_eval_provider<'a, 'tcx>(
340
350
trace ! ( "const eval instance: {:?}, {:?}" , instance, key. param_env) ;
341
351
let miri_result = :: interpret:: eval_body ( tcx, instance, key. param_env ) ;
342
352
match ( miri_result, old_result) {
343
- ( ( Err ( err) , ecx ) , Ok ( ok) ) => {
353
+ ( Err ( err) , Ok ( ok) ) => {
344
354
trace ! ( "miri failed, ctfe returned {:?}" , ok) ;
345
355
tcx. sess . span_warn (
346
356
tcx. def_span ( key. value . 0 ) ,
347
357
"miri failed to eval, while ctfe succeeded" ,
348
358
) ;
359
+ let ecx = mk_eval_cx ( tcx, instance, key. param_env ) . unwrap ( ) ;
349
360
let ( ) = unwrap_miri ( & ecx, Err ( err) ) ;
350
361
Ok ( ok)
351
362
} ,
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 ( ) ;
357
366
check_ctfe_against_miri ( & mut ecx, miri_val, miri_ty, ctfe. val ) ;
358
367
Ok ( ctfe)
359
368
}
0 commit comments