Skip to content

Commit

Permalink
Evaluated computed values to constants.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Sep 20, 2023
1 parent e64137c commit 2767c49
Show file tree
Hide file tree
Showing 16 changed files with 516 additions and 181 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_const_eval/src/interpret/discriminant.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Functions for reading and writing discriminants of multi-variant layouts (enums and generators).

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};

Expand Down Expand Up @@ -245,11 +246,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);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,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 => {
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,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!(layout.is_sized(), "immediates must be sized");
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,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)?;
}
}
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,20 @@ impl<'tcx> ConstValue<'tcx> {
// This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
}

pub fn has_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
let (alloc, start, end) = match *self {
ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
ConstValue::Scalar(Scalar::Ptr(..)) => return true,
ConstValue::Slice { data, start, end } => {
(data, Size::from_bytes(start), Size::from_bytes(end))
}
ConstValue::Indirect { alloc_id, offset } => {
(tcx.global_alloc(alloc_id).unwrap_memory(), offset, offset + size)
}
};
!alloc.inner().provenance().range_empty(super::AllocRange::from(start..end), &tcx)
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_mir_transform/src/dataflow_const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
TrackElem::Discriminant => {
let variant = self.ecx.read_discriminant(op).ok()?;
let discr_value = self.ecx.discriminant_for_variant(op.layout, variant).ok()?;
let discr_value =
self.ecx.discriminant_for_variant(op.layout.ty, variant).ok()?;
Some(discr_value.into())
}
TrackElem::DerefLen => {
Expand Down Expand Up @@ -499,7 +500,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
return None;
}
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()?;
let discr_value =
self.ecx.discriminant_for_variant(enum_ty_layout.ty, variant_index).ok()?;
Some(discr_value.to_scalar())
}

Expand Down Expand Up @@ -693,7 +695,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
}
}

struct DummyMachine;
pub(crate) struct DummyMachine;

impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachine {
rustc_const_eval::interpret::compile_time_machine!(<'mir, 'tcx>);
Expand All @@ -708,8 +710,9 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
}

fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
unimplemented!()
false
}

fn alignment_check_failed(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_has: Align,
Expand Down
Loading

0 comments on commit 2767c49

Please sign in to comment.