Skip to content

Commit cc7a9d6

Browse files
committed
Auto merge of rust-lang#115705 - cjgillot:const-prop-aggregate, r=oli-obk
Read from non-scalar constants and statics in dataflow const-prop DataflowConstProp is designed to handle scalar values. When MIR features an assignment from a non-scalar constant, we need to manually decompose it into the custom state space. This PR tweaks interpreter callbacks to allow reusing `eval_mir_constant` without having a stack frame to get a span from. r? `@oli-obk` cc `@jachris`
2 parents deb708a + 6984030 commit cc7a9d6

26 files changed

+1071
-143
lines changed

compiler/rustc_const_eval/src/interpret/discriminant.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
247247
&self,
248248
layout: TyAndLayout<'tcx>,
249249
variant: VariantIdx,
250-
) -> InterpResult<'tcx, Scalar<M::Provenance>> {
250+
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
251251
let discr_layout = self.layout_of(layout.ty.discriminant_ty(*self.tcx))?;
252-
Ok(match layout.ty.discriminant_for_variant(*self.tcx, variant) {
252+
let discr_value = match layout.ty.discriminant_for_variant(*self.tcx, variant) {
253253
Some(discr) => {
254254
// This type actually has discriminants.
255255
assert_eq!(discr.ty, discr_layout.ty);
@@ -260,6 +260,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
260260
assert_eq!(variant.as_u32(), 0);
261261
Scalar::from_uint(variant.as_u32(), discr_layout.size)
262262
}
263-
})
263+
};
264+
Ok(ImmTy::from_scalar(discr_value, discr_layout))
264265
}
265266
}

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
222222
let place = self.deref_pointer(&args[0])?;
223223
let variant = self.read_discriminant(&place)?;
224224
let discr = self.discriminant_for_variant(place.layout, variant)?;
225-
self.write_scalar(discr, dest)?;
225+
self.write_immediate(*discr, dest)?;
226226
}
227227
sym::exact_div => {
228228
let l = self.read_immediate(&args[0])?;

compiler/rustc_const_eval/src/interpret/step.rs

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

compiler/rustc_mir_dataflow/src/value_analysis.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
532532
/// places that are non-overlapping or identical.
533533
///
534534
/// The target place must have been flooded before calling this method.
535-
fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map) {
535+
pub fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map) {
536536
let StateData::Reachable(values) = &mut self.0 else { return };
537537

538538
// If both places are tracked, we copy the value to the target.
@@ -928,6 +928,31 @@ impl Map {
928928
f(v)
929929
}
930930
}
931+
932+
/// Invoke a function on each value in the given place and all descendants.
933+
pub fn for_each_projection_value<O>(
934+
&self,
935+
root: PlaceIndex,
936+
value: O,
937+
project: &mut impl FnMut(TrackElem, &O) -> Option<O>,
938+
f: &mut impl FnMut(PlaceIndex, &O),
939+
) {
940+
// Fast path is there is nothing to do.
941+
if self.inner_values[root].is_empty() {
942+
return;
943+
}
944+
945+
if self.places[root].value_index.is_some() {
946+
f(root, &value)
947+
}
948+
949+
for child in self.children(root) {
950+
let elem = self.places[child].proj_elem.unwrap();
951+
if let Some(value) = project(elem, &value) {
952+
self.for_each_projection_value(child, value, project, f);
953+
}
954+
}
955+
}
931956
}
932957

933958
/// This is the information tracked for every [`PlaceIndex`] and is stored by [`Map`].

compiler/rustc_mir_transform/src/const_prop.rs

+21-23
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,30 @@ const MAX_ALLOC_LIMIT: u64 = 1024;
3232

3333
/// Macro for machine-specific `InterpError` without allocation.
3434
/// (These will never be shown to the user, but they help diagnose ICEs.)
35-
macro_rules! throw_machine_stop_str {
36-
($($tt:tt)*) => {{
37-
// We make a new local type for it. The type itself does not carry any information,
38-
// but its vtable (for the `MachineStopType` trait) does.
39-
#[derive(Debug)]
40-
struct Zst;
41-
// Printing this type shows the desired string.
42-
impl std::fmt::Display for Zst {
43-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44-
write!(f, $($tt)*)
45-
}
35+
pub(crate) macro throw_machine_stop_str($($tt:tt)*) {{
36+
// We make a new local type for it. The type itself does not carry any information,
37+
// but its vtable (for the `MachineStopType` trait) does.
38+
#[derive(Debug)]
39+
struct Zst;
40+
// Printing this type shows the desired string.
41+
impl std::fmt::Display for Zst {
42+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43+
write!(f, $($tt)*)
4644
}
45+
}
4746

48-
impl rustc_middle::mir::interpret::MachineStopType for Zst {
49-
fn diagnostic_message(&self) -> rustc_errors::DiagnosticMessage {
50-
self.to_string().into()
51-
}
52-
53-
fn add_args(
54-
self: Box<Self>,
55-
_: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue<'static>),
56-
) {}
47+
impl rustc_middle::mir::interpret::MachineStopType for Zst {
48+
fn diagnostic_message(&self) -> rustc_errors::DiagnosticMessage {
49+
self.to_string().into()
5750
}
58-
throw_machine_stop!(Zst)
59-
}};
60-
}
51+
52+
fn add_args(
53+
self: Box<Self>,
54+
_: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue<'static>),
55+
) {}
56+
}
57+
throw_machine_stop!(Zst)
58+
}}
6159

6260
pub struct ConstProp;
6361

0 commit comments

Comments
 (0)