Evaluate computed values to constants.
This commit is contained in:
parent
afd631cc0c
commit
38c86b0798
15 changed files with 546 additions and 191 deletions
|
@ -1,7 +1,8 @@
|
|||
//! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines).
|
||||
|
||||
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_target::abi::{self, TagEncoding};
|
||||
use rustc_target::abi::{VariantIdx, Variants};
|
||||
|
||||
|
@ -244,11 +245,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
|
||||
pub fn discriminant_for_variant(
|
||||
&self,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
variant: VariantIdx,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||
let discr_layout = self.layout_of(layout.ty.discriminant_ty(*self.tcx))?;
|
||||
let discr_value = match layout.ty.discriminant_for_variant(*self.tcx, variant) {
|
||||
let discr_layout = self.layout_of(ty.discriminant_ty(*self.tcx))?;
|
||||
let discr_value = match ty.discriminant_for_variant(*self.tcx, variant) {
|
||||
Some(discr) => {
|
||||
// This type actually has discriminants.
|
||||
assert_eq!(discr.ty, discr_layout.ty);
|
||||
|
|
|
@ -218,7 +218,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
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.ty, variant)?;
|
||||
self.write_immediate(*discr, dest)?;
|
||||
}
|
||||
sym::exact_div => {
|
||||
|
|
|
@ -169,6 +169,16 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
|
|||
ImmTy { imm: val.into(), layout }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_scalar_pair(a: Scalar<Prov>, b: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
|
||||
debug_assert!(
|
||||
matches!(layout.abi, Abi::ScalarPair(..)),
|
||||
"`ImmTy::from_scalar_pair` on non-scalar-pair layout"
|
||||
);
|
||||
let imm = Immediate::ScalarPair(a, b);
|
||||
ImmTy { imm, layout }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Self {
|
||||
debug_assert!(
|
||||
|
|
|
@ -297,7 +297,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Discriminant(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)?;
|
||||
let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
|
||||
self.write_immediate(*discr, &dest)?;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue