Skip to content

Commit 2e0b746

Browse files
committed
Evaluated computed values to constants.
1 parent 8bf4db4 commit 2e0b746

16 files changed

+519
-180
lines changed

compiler/rustc_const_eval/src/interpret/discriminant.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Functions for reading and writing discriminants of multi-variant layouts (enums and generators).
22
3-
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
4-
use rustc_middle::{mir, ty};
3+
use rustc_middle::mir;
4+
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt};
5+
use rustc_middle::ty::{self, Ty};
56
use rustc_target::abi::{self, TagEncoding};
67
use rustc_target::abi::{VariantIdx, Variants};
78

@@ -245,11 +246,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
245246

246247
pub fn discriminant_for_variant(
247248
&self,
248-
layout: TyAndLayout<'tcx>,
249+
ty: Ty<'tcx>,
249250
variant: VariantIdx,
250251
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
251-
let discr_layout = self.layout_of(layout.ty.discriminant_ty(*self.tcx))?;
252-
let discr_value = match layout.ty.discriminant_for_variant(*self.tcx, variant) {
252+
let discr_layout = self.layout_of(ty.discriminant_ty(*self.tcx))?;
253+
let discr_value = match ty.discriminant_for_variant(*self.tcx, variant) {
253254
Some(discr) => {
254255
// This type actually has discriminants.
255256
assert_eq!(discr.ty, discr_layout.ty);

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
219219
sym::discriminant_value => {
220220
let place = self.deref_pointer(&args[0])?;
221221
let variant = self.read_discriminant(&place)?;
222-
let discr = self.discriminant_for_variant(place.layout, variant)?;
222+
let discr = self.discriminant_for_variant(place.layout.ty, variant)?;
223223
self.write_immediate(*discr, dest)?;
224224
}
225225
sym::exact_div => {

compiler/rustc_const_eval/src/interpret/operand.rs

+10
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
163163
ImmTy { imm: val.into(), layout }
164164
}
165165

166+
#[inline]
167+
pub fn from_scalar_pair(a: Scalar<Prov>, b: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
168+
debug_assert!(
169+
matches!(layout.abi, Abi::ScalarPair(..)),
170+
"`ImmTy::from_scalar_pair` on non-scalar-pair layout"
171+
);
172+
let imm = Immediate::ScalarPair(a, b);
173+
ImmTy { imm, layout }
174+
}
175+
166176
#[inline(always)]
167177
pub fn from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Self {
168178
debug_assert!(layout.is_sized(), "immediates must be sized");

compiler/rustc_const_eval/src/interpret/step.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
300300
Discriminant(place) => {
301301
let op = self.eval_place_to_op(place, None)?;
302302
let variant = self.read_discriminant(&op)?;
303-
let discr = self.discriminant_for_variant(op.layout, variant)?;
303+
let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
304304
self.write_immediate(*discr, &dest)?;
305305
}
306306
}

compiler/rustc_middle/src/mir/consts.rs

+12
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,18 @@ impl<'tcx> ConstValue<'tcx> {
172172
let end = end.try_into().unwrap();
173173
Some(data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end))
174174
}
175+
176+
pub fn has_provenance(&self, tcx: TyCtxt<'tcx>, size: Size) -> bool {
177+
let (alloc, start, end) = match *self {
178+
ConstValue::ZeroSized | ConstValue::Scalar(Scalar::Int(_)) => return false,
179+
ConstValue::Scalar(Scalar::Ptr(..)) => return true,
180+
ConstValue::Slice { data, meta } => (data, Size::ZERO, Size::from_bytes(meta)),
181+
ConstValue::Indirect { alloc_id, offset } => {
182+
(tcx.global_alloc(alloc_id).unwrap_memory(), offset, offset + size)
183+
}
184+
};
185+
!alloc.inner().provenance().range_empty(super::AllocRange::from(start..end), &tcx)
186+
}
175187
}
176188

177189
///////////////////////////////////////////////////////////////////////////

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
400400
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
401401
TrackElem::Discriminant => {
402402
let variant = self.ecx.read_discriminant(op).ok()?;
403-
let discr_value = self.ecx.discriminant_for_variant(op.layout, variant).ok()?;
403+
let discr_value =
404+
self.ecx.discriminant_for_variant(op.layout.ty, variant).ok()?;
404405
Some(discr_value.into())
405406
}
406407
TrackElem::DerefLen => {
@@ -499,7 +500,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
499500
return None;
500501
}
501502
let enum_ty_layout = self.tcx.layout_of(self.param_env.and(enum_ty)).ok()?;
502-
let discr_value = self.ecx.discriminant_for_variant(enum_ty_layout, variant_index).ok()?;
503+
let discr_value =
504+
self.ecx.discriminant_for_variant(enum_ty_layout.ty, variant_index).ok()?;
503505
Some(discr_value.to_scalar())
504506
}
505507

@@ -693,7 +695,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
693695
}
694696
}
695697

696-
struct DummyMachine;
698+
pub(crate) struct DummyMachine;
697699

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

710712
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
711-
unimplemented!()
713+
false
712714
}
715+
713716
fn alignment_check_failed(
714717
_ecx: &InterpCx<'mir, 'tcx, Self>,
715718
_has: Align,

0 commit comments

Comments
 (0)