Skip to content

Commit 2eb1917

Browse files
committed
Evaluated computed values to constants.
1 parent ccdb50f commit 2eb1917

16 files changed

+554
-194
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

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

245246
pub fn discriminant_for_variant(
246247
&self,
247-
layout: TyAndLayout<'tcx>,
248+
ty: Ty<'tcx>,
248249
variant: VariantIdx,
249250
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
250-
let discr_layout = self.layout_of(layout.ty.discriminant_ty(*self.tcx))?;
251-
let discr_value = match layout.ty.discriminant_for_variant(*self.tcx, variant) {
251+
let discr_layout = self.layout_of(ty.discriminant_ty(*self.tcx))?;
252+
let discr_value = match ty.discriminant_for_variant(*self.tcx, variant) {
252253
Some(discr) => {
253254
// This type actually has discriminants.
254255
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!(

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
@@ -406,7 +406,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
406406
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
407407
TrackElem::Discriminant => {
408408
let variant = self.ecx.read_discriminant(op).ok()?;
409-
let discr_value = self.ecx.discriminant_for_variant(op.layout, variant).ok()?;
409+
let discr_value =
410+
self.ecx.discriminant_for_variant(op.layout.ty, variant).ok()?;
410411
Some(discr_value.into())
411412
}
412413
TrackElem::DerefLen => {
@@ -507,7 +508,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
507508
return None;
508509
}
509510
let enum_ty_layout = self.tcx.layout_of(self.param_env.and(enum_ty)).ok()?;
510-
let discr_value = self.ecx.discriminant_for_variant(enum_ty_layout, variant_index).ok()?;
511+
let discr_value =
512+
self.ecx.discriminant_for_variant(enum_ty_layout.ty, variant_index).ok()?;
511513
Some(discr_value.to_scalar())
512514
}
513515

@@ -701,7 +703,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
701703
}
702704
}
703705

704-
struct DummyMachine;
706+
pub(crate) struct DummyMachine;
705707

706708
impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachine {
707709
rustc_const_eval::interpret::compile_time_machine!(<'mir, 'tcx>);
@@ -716,8 +718,9 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
716718
}
717719

718720
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
719-
unimplemented!()
721+
false
720722
}
723+
721724
fn alignment_check_failed(
722725
_ecx: &InterpCx<'mir, 'tcx, Self>,
723726
_has: Align,

0 commit comments

Comments
 (0)