@@ -35,6 +35,16 @@ const STEPS_UNTIL_DETECTOR_ENABLED: isize = 1_000_000;
3535/// Should be a power of two for performance reasons.
3636const DETECTOR_SNAPSHOT_PERIOD : isize = 256 ;
3737
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.
3848pub fn mk_borrowck_eval_cx < ' a , ' mir , ' tcx > (
3949 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
4050 instance : Instance < ' tcx > ,
@@ -43,9 +53,22 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
4353) -> EvalResult < ' tcx , CompileTimeEvalContext < ' a , ' mir , ' tcx > > {
4454 debug ! ( "mk_borrowck_eval_cx: {:?}" , instance) ;
4555 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 > > {
4668 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
4972 ecx. stack . push ( interpret:: Frame {
5073 block : mir:: START_BLOCK ,
5174 locals : IndexVec :: new ( ) ,
@@ -60,24 +83,23 @@ pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
6083 Ok ( ecx)
6184}
6285
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 > (
6495 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
6596 instance : Instance < ' tcx > ,
6697 param_env : ty:: ParamEnv < ' tcx > ,
6798) -> EvalResult < ' tcx , CompileTimeEvalContext < ' a , ' tcx , ' tcx > > {
6899 debug ! ( "mk_eval_cx: {:?}, {:?}" , instance, param_env) ;
69100 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)
81103}
82104
83105pub ( crate ) fn eval_promoted < ' a , ' mir , ' tcx > (
0 commit comments