+ use rustc_target::abi::{TagEncoding, Int, Variants};
+
+ match &operand.layout().variants {
+ Variants::Single { index } => {
+ let discr = operand.layout().ty.discriminant_for_variant(fx.codegen_cx.tcx, *index).unwrap();
+ let discr = if discr.ty.is_signed() {
+ rustc_middle::mir::interpret::sign_extend(discr.val, fx.layout_of(discr.ty).size)
+ } else {
+ discr.val
+ };
+
+ let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr);
+ lval.write_cvalue(fx, discr);
+ }
+ Variants::Multiple {
+ tag,
+ tag_field,
+ tag_encoding: TagEncoding::Direct,
+ variants: _,
+ } => {
+ let cast_to = fx.clif_type(dest_layout.ty).unwrap();
+
+ // Read the tag/niche-encoded discriminant from memory.
+ let encoded_discr = operand.value_field(fx, mir::Field::new(*tag_field));
+ let encoded_discr = encoded_discr.load_scalar(fx);
+
+ // Decode the discriminant (specifically if it's niche-encoded).
+ let signed = match tag.value {
+ Int(_, signed) => signed,
+ _ => false,
+ };
+ let val = clif_intcast(fx, encoded_discr, cast_to, signed);
+ let val = CValue::by_val(val, dest_layout);
+ lval.write_cvalue(fx, val);
+ }
+ Variants::Multiple { ..} => unreachable!(),
+ }