2 use crate::mir
::operand
::OperandRef
;
5 use rustc_middle
::mir
::interpret
::{ConstValue, ErrorHandled}
;
6 use rustc_middle
::ty
::layout
::HasTyCtxt
;
7 use rustc_middle
::ty
::{self, Ty}
;
8 use rustc_span
::source_map
::Span
;
9 use rustc_target
::abi
::Abi
;
11 use super::FunctionCx
;
13 impl<'a
, 'tcx
, Bx
: BuilderMethods
<'a
, 'tcx
>> FunctionCx
<'a
, 'tcx
, Bx
> {
14 pub fn eval_mir_constant_to_operand(
17 constant
: &mir
::Constant
<'tcx
>,
18 ) -> Result
<OperandRef
<'tcx
, Bx
::Value
>, ErrorHandled
> {
19 let val
= self.eval_mir_constant(constant
)?
;
20 let ty
= self.monomorphize(constant
.ty());
21 Ok(OperandRef
::from_const(bx
, val
, ty
))
24 pub fn eval_mir_constant(
26 constant
: &mir
::Constant
<'tcx
>,
27 ) -> Result
<ConstValue
<'tcx
>, ErrorHandled
> {
28 let ct
= self.monomorphize(constant
.literal
);
30 mir
::ConstantKind
::Ty(ct
) => match ct
.kind() {
31 ty
::ConstKind
::Unevaluated(uv
) => uv
.expand(),
32 ty
::ConstKind
::Value(val
) => {
33 return Ok(self.cx
.tcx().valtree_to_const_val((ct
.ty(), val
)));
37 "encountered bad ConstKind after monomorphizing: {:?}",
41 mir
::ConstantKind
::Unevaluated(uv
, _
) => uv
,
42 mir
::ConstantKind
::Val(val
, _
) => return Ok(val
),
45 self.cx
.tcx().const_eval_resolve(ty
::ParamEnv
::reveal_all(), uv
, None
).map_err(|err
| {
47 ErrorHandled
::Reported(_
) => {
48 self.cx
.tcx().sess
.emit_err(errors
::ErroneousConstant { span: constant.span }
);
50 ErrorHandled
::TooGeneric
=> {
55 .emit_bug(errors
::PolymorphicConstantTooGeneric { span: constant.span }
);
62 /// process constant containing SIMD shuffle indices
63 pub fn simd_shuffle_indices(
68 constant
: Result
<ConstValue
<'tcx
>, ErrorHandled
>,
69 ) -> (Bx
::Value
, Ty
<'tcx
>) {
72 let field_ty
= ty
.builtin_index().unwrap();
73 let c
= mir
::ConstantKind
::from_value(val
, ty
);
74 let values
: Vec
<_
> = bx
76 .destructure_mir_constant(ty
::ParamEnv
::reveal_all(), c
)
80 if let Some(prim
) = field
.try_to_scalar() {
81 let layout
= bx
.layout_of(field_ty
);
82 let Abi
::Scalar(scalar
) = layout
.abi
else {
83 bug
!("from_const: invalid ByVal layout: {:#?}", layout
);
85 bx
.scalar_to_backend(prim
, scalar
, bx
.immediate_backend_type(layout
))
87 bug
!("simd shuffle field {:?}", field
)
91 let llval
= bx
.const_struct(&values
, false);
95 bx
.tcx().sess
.emit_err(errors
::ShuffleIndicesEvaluation { span }
);
96 // We've errored, so we don't have to produce working code.
97 let ty
= self.monomorphize(ty
);
98 let llty
= bx
.backend_type(bx
.layout_of(ty
));
99 (bx
.const_undef(llty
), ty
)