@@ -3,10 +3,11 @@ use either::{Left, Right};
33use  rustc_hir:: def:: DefKind ; 
44use  rustc_middle:: mir:: interpret:: { AllocId ,  ErrorHandled ,  InterpErrorInfo } ; 
55use  rustc_middle:: mir:: { self ,  ConstAlloc ,  ConstValue } ; 
6+ use  rustc_middle:: query:: TyCtxtAt ; 
67use  rustc_middle:: traits:: Reveal ; 
78use  rustc_middle:: ty:: layout:: LayoutOf ; 
89use  rustc_middle:: ty:: print:: with_no_trimmed_paths; 
9- use  rustc_middle:: ty:: { self ,  TyCtxt } ; 
10+ use  rustc_middle:: ty:: { self ,  Ty ,   TyCtxt } ; 
1011use  rustc_span:: def_id:: LocalDefId ; 
1112use  rustc_span:: Span ; 
1213use  rustc_target:: abi:: { self ,  Abi } ; 
@@ -87,13 +88,16 @@ fn eval_body_using_ecx<'mir, 'tcx>(
8788} 
8889
8990/// The `InterpCx` is only meant to be used to do field and index projections into constants for 
90- /// `simd_shuffle` and const patterns in match arms. It never performs alignment checks. 
91+ /// `simd_shuffle` and const patterns in match arms. 
92+ /// 
93+ /// This should *not* be used to do any actual interpretation. In particular, alignment checks are 
94+ /// turned off! 
9195/// 
9296/// The function containing the `match` that is currently being analyzed may have generic bounds 
9397/// that inform us about the generic bounds of the constant. E.g., using an associated constant 
9498/// of a function's generic parameter will require knowledge about the bounds on the generic 
9599/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. 
96- pub ( crate )  fn  mk_eval_cx < ' mir ,  ' tcx > ( 
100+ pub ( crate )  fn  mk_eval_cx_to_read_const_val < ' mir ,  ' tcx > ( 
97101    tcx :  TyCtxt < ' tcx > , 
98102    root_span :  Span , 
99103    param_env :  ty:: ParamEnv < ' tcx > , 
@@ -108,6 +112,19 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>(
108112    ) 
109113} 
110114
115+ /// Create an interpreter context to inspect the given `ConstValue`. 
116+ /// Returns both the context and an `OpTy` that represents the constant. 
117+ pub  fn  mk_eval_cx_for_const_val < ' mir ,  ' tcx > ( 
118+     tcx :  TyCtxtAt < ' tcx > , 
119+     param_env :  ty:: ParamEnv < ' tcx > , 
120+     val :  mir:: ConstValue < ' tcx > , 
121+     ty :  Ty < ' tcx > , 
122+ )  -> Option < ( CompileTimeEvalContext < ' mir ,  ' tcx > ,  OpTy < ' tcx > ) >  { 
123+     let  ecx = mk_eval_cx_to_read_const_val ( tcx. tcx ,  tcx. span ,  param_env,  CanAccessMutGlobal :: No ) ; 
124+     let  op = ecx. const_val_to_op ( val,  ty,  None ) . ok ( ) ?; 
125+     Some ( ( ecx,  op) ) 
126+ } 
127+ 
111128/// This function converts an interpreter value into a MIR constant. 
112129/// 
113130/// The `for_diagnostics` flag turns the usual rules for returning `ConstValue::Scalar` into a 
@@ -203,7 +220,7 @@ pub(crate) fn turn_into_const_value<'tcx>(
203220    let  def_id = cid. instance . def . def_id ( ) ; 
204221    let  is_static = tcx. is_static ( def_id) ; 
205222    // This is just accessing an already computed constant, so no need to check alignment here. 
206-     let  ecx = mk_eval_cx ( 
223+     let  ecx = mk_eval_cx_to_read_const_val ( 
207224        tcx, 
208225        tcx. def_span ( key. value . instance . def_id ( ) ) , 
209226        key. param_env , 
0 commit comments