@@ -35,6 +35,16 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000;
35
35
/// Should be a power of two for performance reasons.
36
36
const DETECTOR_SNAPSHOT_PERIOD : isize = 256 ;
37
37
38
+ /// Warning: do not use this function if you expect to start interpreting the given `Mir`.
39
+ /// The `EvalContext` is only meant to be used to query values from constants and statics.
40
+ ///
41
+ /// This function is used during const propagation. We cannot use `mk_eval_cx`, because copy
42
+ /// propagation happens *during* the computation of the MIR of the current function. So if we
43
+ /// tried to call the `optimized_mir` query, we'd get a cycle error because we are (transitively)
44
+ /// inside the `optimized_mir` query of the `Instance` given.
45
+ ///
46
+ /// Since we are looking at the MIR of the function in an abstract manner, we don't have a
47
+ /// `ParamEnv` available to us. This function creates a `ParamEnv` for the given instance.
38
48
pub fn mk_borrowck_eval_cx < ' a , ' mir , ' tcx > (
39
49
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
40
50
instance : Instance < ' tcx > ,
@@ -43,9 +53,22 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
43
53
) -> EvalResult < ' tcx , CompileTimeEvalContext < ' a , ' mir , ' tcx > > {
44
54
debug ! ( "mk_borrowck_eval_cx: {:?}" , instance) ;
45
55
let param_env = tcx. param_env ( instance. def_id ( ) ) ;
56
+ mk_eval_cx_inner ( tcx, instance, mir, span, param_env)
57
+ }
58
+
59
+ /// This is just a helper function to reduce code duplication between `mk_borrowck_eval_cx` and
60
+ /// `mk_eval_cx`. Do not call this function directly.
61
+ fn mk_eval_cx_inner < ' a , ' mir , ' tcx > (
62
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
63
+ instance : Instance < ' tcx > ,
64
+ mir : & ' mir mir:: Mir < ' tcx > ,
65
+ span : Span ,
66
+ param_env : ty:: ParamEnv < ' tcx > ,
67
+ ) -> EvalResult < ' tcx , CompileTimeEvalContext < ' a , ' mir , ' tcx > > {
46
68
let mut ecx = EvalContext :: new ( tcx. at ( span) , param_env, CompileTimeInterpreter :: new ( ) ) ;
47
- // insert a stack frame so any queries have the correct substs
48
- // cannot use `push_stack_frame`; if we do `const_prop` explodes
69
+ // Insert a stack frame so any queries have the correct substs.
70
+ // We also avoid all the extra work performed by push_stack_frame,
71
+ // like initializing local variables
49
72
ecx. stack . push ( interpret:: Frame {
50
73
block : mir:: START_BLOCK ,
51
74
locals : IndexVec :: new ( ) ,
@@ -60,24 +83,23 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
60
83
Ok ( ecx)
61
84
}
62
85
63
- pub fn mk_eval_cx < ' a , ' tcx > (
86
+ /// Warning: do not use this function if you expect to start interpreting the given `Mir`.
87
+ /// The `EvalContext` is only meant to be used to do field and index projections into constants for
88
+ /// `simd_shuffle` and const patterns in match arms.
89
+ ///
90
+ /// The function containing the `match` that is currently being analyzed may have generic bounds
91
+ /// that inform us about the generic bounds of the constant. E.g. using an associated constant
92
+ /// of a function's generic parameter will require knowledge about the bounds on the generic
93
+ /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
94
+ fn mk_eval_cx < ' a , ' tcx > (
64
95
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
65
96
instance : Instance < ' tcx > ,
66
97
param_env : ty:: ParamEnv < ' tcx > ,
67
98
) -> EvalResult < ' tcx , CompileTimeEvalContext < ' a , ' tcx , ' tcx > > {
68
99
debug ! ( "mk_eval_cx: {:?}, {:?}" , instance, param_env) ;
69
100
let span = tcx. def_span ( instance. def_id ( ) ) ;
70
- let mut ecx = EvalContext :: new ( tcx. at ( span) , param_env, CompileTimeInterpreter :: new ( ) ) ;
71
- let mir = ecx. load_mir ( instance. def ) ?;
72
- // insert a stack frame so any queries have the correct substs
73
- ecx. push_stack_frame (
74
- instance,
75
- mir. span ,
76
- mir,
77
- None ,
78
- StackPopCleanup :: Goto ( None ) , // never pop
79
- ) ?;
80
- Ok ( ecx)
101
+ let mir = tcx. optimized_mir ( instance. def . def_id ( ) ) ;
102
+ mk_eval_cx_inner ( tcx, instance, mir, span, param_env)
81
103
}
82
104
83
105
pub ( crate ) fn eval_promoted < ' a , ' mir , ' tcx > (
0 commit comments