diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 6c35fb01a93..440ee06e7fe 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -247,9 +247,9 @@ pub fn discriminant_for_variant( &self, layout: TyAndLayout<'tcx>, variant: VariantIdx, - ) -> InterpResult<'tcx, Scalar> { + ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { let discr_layout = self.layout_of(layout.ty.discriminant_ty(*self.tcx))?; - Ok(match layout.ty.discriminant_for_variant(*self.tcx, variant) { + let discr_value = match layout.ty.discriminant_for_variant(*self.tcx, variant) { Some(discr) => { // This type actually has discriminants. assert_eq!(discr.ty, discr_layout.ty); @@ -260,6 +260,7 @@ pub fn discriminant_for_variant( assert_eq!(variant.as_u32(), 0); Scalar::from_uint(variant.as_u32(), discr_layout.size) } - }) + }; + Ok(ImmTy::from_scalar(discr_value, discr_layout)) } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 7feed74ceae..e886fd23ff5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -221,7 +221,7 @@ pub fn emulate_intrinsic( sym::discriminant_value => { let place = self.deref_pointer(&args[0])?; let variant = self.read_discriminant(&place)?; - let discr = self.discriminant_for_variant(place.layout, variant)?; + let discr = self.discriminant_for_variant(place.layout, variant)?.to_scalar(); self.write_scalar(discr, dest)?; } sym::exact_div => { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 57f99bd8f61..cf1f7ff75e1 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -301,7 +301,7 @@ pub fn eval_rvalue_into_place( let op = self.eval_place_to_op(place, None)?; let variant = self.read_discriminant(&op)?; let discr = self.discriminant_for_variant(op.layout, variant)?; - self.write_scalar(discr, &dest)?; + self.write_immediate(*discr, &dest)?; } } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a67bc53d2b4..9f3f396a237 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -405,10 +405,8 @@ fn assign_constant( TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(), TrackElem::Discriminant => { let variant = self.ecx.read_discriminant(op).ok()?; - let scalar = self.ecx.discriminant_for_variant(op.layout, variant).ok()?; - let discr_ty = op.layout.ty.discriminant_ty(self.tcx); - let layout = self.tcx.layout_of(self.param_env.and(discr_ty)).ok()?; - Some(ImmTy::from_scalar(scalar, layout).into()) + let discr_value = self.ecx.discriminant_for_variant(op.layout, variant).ok()?; + Some(discr_value.into()) } TrackElem::DerefLen => { let op: OpTy<'_> = self.ecx.deref_pointer(op).ok()?.into(); @@ -505,10 +503,9 @@ fn eval_discriminant(&self, enum_ty: Ty<'tcx>, variant_index: VariantIdx) -> Opt if !enum_ty.is_enum() { return None; } - let discr = enum_ty.discriminant_for_variant(self.tcx, variant_index)?; - let discr_layout = self.tcx.layout_of(self.param_env.and(discr.ty)).ok()?; - let discr_value = Scalar::try_from_uint(discr.val, discr_layout.size)?; - Some(discr_value) + let enum_ty_layout = self.tcx.layout_of(self.param_env.and(enum_ty)).ok()?; + let discr_value = self.ecx.discriminant_for_variant(enum_ty_layout, variant_index).ok()?; + Some(discr_value.to_scalar()) } fn wrap_immediate(&self, imm: Immediate) -> FlatSet {