@@ -3,10 +3,11 @@ use either::{Left, Right};
3
3
use rustc_hir:: def:: DefKind ;
4
4
use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , InterpErrorInfo } ;
5
5
use rustc_middle:: mir:: { self , ConstAlloc , ConstValue } ;
6
+ use rustc_middle:: query:: TyCtxtAt ;
6
7
use rustc_middle:: traits:: Reveal ;
7
8
use rustc_middle:: ty:: layout:: LayoutOf ;
8
9
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
9
- use rustc_middle:: ty:: { self , TyCtxt } ;
10
+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
10
11
use rustc_span:: def_id:: LocalDefId ;
11
12
use rustc_span:: Span ;
12
13
use rustc_target:: abi:: { self , Abi } ;
@@ -87,13 +88,16 @@ fn eval_body_using_ecx<'mir, 'tcx>(
87
88
}
88
89
89
90
/// 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!
91
95
///
92
96
/// The function containing the `match` that is currently being analyzed may have generic bounds
93
97
/// that inform us about the generic bounds of the constant. E.g., using an associated constant
94
98
/// of a function's generic parameter will require knowledge about the bounds on the generic
95
99
/// 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 > (
97
101
tcx : TyCtxt < ' tcx > ,
98
102
root_span : Span ,
99
103
param_env : ty:: ParamEnv < ' tcx > ,
@@ -108,6 +112,19 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>(
108
112
)
109
113
}
110
114
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
+
111
128
/// This function converts an interpreter value into a MIR constant.
112
129
///
113
130
/// 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>(
203
220
let def_id = cid. instance . def . def_id ( ) ;
204
221
let is_static = tcx. is_static ( def_id) ;
205
222
// 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 (
207
224
tcx,
208
225
tcx. def_span ( key. value . instance . def_id ( ) ) ,
209
226
key. param_env ,
0 commit comments