Skip to content

Commit 34ea559

Browse files
authored
Rollup merge of #64991 - wesleywiser:fix_too_eager_const_prop, r=oli-obk
[const-prop] Correctly handle locals that can't be propagated `const_prop()` now handles writing the Rvalue into the Place in the stack frame for us. So if we're not supposed to propagate that value, we need to clear it. r? @oli-obk Fixes #64970
2 parents 028ffd1 + 3a8932d commit 34ea559

File tree

3 files changed

+28
-29
lines changed

3 files changed

+28
-29
lines changed

src/librustc_mir/transform/const_prop.rs

+5-29
Original file line numberDiff line numberDiff line change
@@ -335,34 +335,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
335335
}
336336

337337
fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
338-
let l = &self.ecx.frame().locals[local];
339-
340-
// If the local is `Unitialized` or `Dead` then we haven't propagated a value into it.
341-
//
342-
// `InterpCx::access_local()` mostly takes care of this for us however, for ZSTs,
343-
// it will synthesize a value for us. In doing so, that will cause the
344-
// `get_const(l).is_empty()` assert right before we call `set_const()` in `visit_statement`
345-
// to fail.
346-
if let LocalValue::Uninitialized | LocalValue::Dead = l.value {
347-
return None;
348-
}
349-
350338
self.ecx.access_local(self.ecx.frame(), local, None).ok()
351339
}
352340

353-
fn set_const(&mut self, local: Local, c: Const<'tcx>) {
354-
let frame = self.ecx.frame_mut();
355-
356-
if let Some(layout) = frame.locals[local].layout.get() {
357-
debug_assert_eq!(c.layout, layout);
358-
}
359-
360-
frame.locals[local] = LocalState {
361-
value: LocalValue::Live(*c),
362-
layout: Cell::new(Some(c.layout)),
363-
};
364-
}
365-
366341
fn remove_const(&mut self, local: Local) {
367342
self.ecx.frame_mut().locals[local] = LocalState {
368343
value: LocalValue::Uninitialized,
@@ -735,10 +710,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
735710
place) {
736711
trace!("checking whether {:?} can be stored to {:?}", value, local);
737712
if self.can_const_prop[local] {
738-
trace!("storing {:?} to {:?}", value, local);
739-
assert!(self.get_const(local).is_none() ||
740-
self.get_const(local) == Some(value));
741-
self.set_const(local, value);
713+
trace!("stored {:?} to {:?}", value, local);
714+
assert_eq!(self.get_const(local), Some(value));
742715

743716
if self.should_const_prop() {
744717
self.replace_with_const(
@@ -747,6 +720,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
747720
statement.source_info,
748721
);
749722
}
723+
} else {
724+
trace!("can't propagate {:?} to {:?}", value, local);
725+
self.remove_const(local);
750726
}
751727
}
752728
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-pass
2+
3+
fn main() {
4+
foo(10);
5+
}
6+
7+
fn foo(mut n: i32) {
8+
if false {
9+
n = 0i32;
10+
}
11+
12+
if n > 0i32 {
13+
1i32 / n;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: unused arithmetic operation that must be used
2+
--> $DIR/issue-64970.rs:13:9
3+
|
4+
LL | 1i32 / n;
5+
| ^^^^^^^^
6+
|
7+
= note: `#[warn(unused_must_use)]` on by default
8+

0 commit comments

Comments
 (0)