1 // Not in interpret to make sure we do not use private implementation details
4 use rustc::ty::layout::VariantIdx;
5 use rustc::ty::{self, TyCtxt};
6 use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
8 use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx};
16 pub use eval_queries::*;
17 pub use fn_queries::*;
20 /// Extracts a field of a (variant of a) const.
21 // this function uses `unwrap` copiously, because an already validated constant must have valid
22 // fields and can thus never fail outside of compiler bugs
23 pub(crate) fn const_field<'tcx>(
25 param_env: ty::ParamEnv<'tcx>,
26 variant: Option<VariantIdx>,
28 value: &'tcx ty::Const<'tcx>,
29 ) -> &'tcx ty::Const<'tcx> {
30 trace!("const_field: {:?}, {:?}", field, value);
31 let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
32 // get the operand again
33 let op = ecx.eval_const_to_op(value, None).unwrap();
35 let down = match variant {
37 Some(variant) => ecx.operand_downcast(op, variant).unwrap(),
40 let field = ecx.operand_field(down, field.index() as u64).unwrap();
41 // and finally move back to the const world, always normalizing because
42 // this is not called for statics.
43 op_to_const(&ecx, field)
46 pub(crate) fn const_caller_location<'tcx>(
48 (file, line, col): (Symbol, u32, u32),
49 ) -> &'tcx ty::Const<'tcx> {
50 trace!("const_caller_location: {}:{}:{}", file, line, col);
51 let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);
53 let loc_ty = tcx.caller_location_ty();
54 let loc_place = ecx.alloc_caller_location(file, line, col);
55 intern_const_alloc_recursive(&mut ecx, None, loc_place, false).unwrap();
56 let loc_const = ty::Const {
58 val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())),
61 tcx.mk_const(loc_const)
64 // this function uses `unwrap` copiously, because an already validated constant must have valid
65 // fields and can thus never fail outside of compiler bugs
66 pub(crate) fn const_variant_index<'tcx>(
68 param_env: ty::ParamEnv<'tcx>,
69 val: &'tcx ty::Const<'tcx>,
71 trace!("const_variant_index: {:?}", val);
72 let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
73 let op = ecx.eval_const_to_op(val, None).unwrap();
74 ecx.read_discriminant(op).unwrap().1