Skip to content

Commit 78bc696

Browse files
committed
Evaluate computed values to constants.
1 parent cbfaa92 commit 78bc696

16 files changed

+554
-194
lines changed

compiler/rustc_const_eval/src/interpret/discriminant.rs

Lines changed: 6 additions & 5 deletions
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 coroutines).
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

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

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,16 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
168168
ImmTy { imm: val.into(), layout }
169169
}
170170

171+
#[inline]
172+
pub fn from_scalar_pair(a: Scalar<Prov>, b: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
173+
debug_assert!(
174+
matches!(layout.abi, Abi::ScalarPair(..)),
175+
"`ImmTy::from_scalar_pair` on non-scalar-pair layout"
176+
);
177+
let imm = Immediate::ScalarPair(a, b);
178+
ImmTy { imm, layout }
179+
}
180+
171181
#[inline(always)]
172182
pub fn from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Self {
173183
debug_assert!(

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
297297
Discriminant(place) => {
298298
let op = self.eval_place_to_op(place, None)?;
299299
let variant = self.read_discriminant(&op)?;
300-
let discr = self.discriminant_for_variant(op.layout, variant)?;
300+
let discr = self.discriminant_for_variant(op.layout.ty, variant)?;
301301
self.write_immediate(*discr, &dest)?;
302302
}
303303
}

compiler/rustc_middle/src/mir/consts.rs

Lines changed: 12 additions & 0 deletions
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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
405405
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
406406
TrackElem::Discriminant => {
407407
let variant = self.ecx.read_discriminant(op).ok()?;
408-
let discr_value = self.ecx.discriminant_for_variant(op.layout, variant).ok()?;
408+
let discr_value =
409+
self.ecx.discriminant_for_variant(op.layout.ty, variant).ok()?;
409410
Some(discr_value.into())
410411
}
411412
TrackElem::DerefLen => {
@@ -506,7 +507,8 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
506507
return None;
507508
}
508509
let enum_ty_layout = self.tcx.layout_of(self.param_env.and(enum_ty)).ok()?;
509-
let discr_value = self.ecx.discriminant_for_variant(enum_ty_layout, variant_index).ok()?;
510+
let discr_value =
511+
self.ecx.discriminant_for_variant(enum_ty_layout.ty, variant_index).ok()?;
510512
Some(discr_value.to_scalar())
511513
}
512514

@@ -700,7 +702,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
700702
}
701703
}
702704

703-
struct DummyMachine;
705+
pub(crate) struct DummyMachine;
704706

705707
impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachine {
706708
rustc_const_eval::interpret::compile_time_machine!(<'mir, 'tcx>);
@@ -713,7 +715,7 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
713715
}
714716

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

719721
fn before_access_global(

0 commit comments

Comments
 (0)