@@ -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