Skip to content

Commit 86c7c4d

Browse files
committed
[const-prop] Replace Use handling with use of InterpCx
1 parent bc17936 commit 86c7c4d

File tree

2 files changed

+26
-25
lines changed

2 files changed

+26
-25
lines changed

src/librustc_mir/interpret/step.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
132132
///
133133
/// There is no separate `eval_rvalue` function. Instead, the code for handling each rvalue
134134
/// type writes its results directly into the memory specified by the place.
135-
fn eval_rvalue_into_place(
135+
pub fn eval_rvalue_into_place(
136136
&mut self,
137137
rvalue: &mir::Rvalue<'tcx>,
138138
place: &mir::Place<'tcx>,

src/librustc_mir/transform/const_prop.rs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
300300
rvalue: &Rvalue<'tcx>,
301301
place_layout: TyLayout<'tcx>,
302302
source_info: SourceInfo,
303+
place: &Place<'tcx>,
303304
) -> Option<Const<'tcx>> {
304305
let span = source_info.span;
305306
match *rvalue {
306-
Rvalue::Use(ref op) => {
307-
self.eval_operand(op, source_info)
307+
Rvalue::Use(_) |
308+
Rvalue::Len(_) => {
309+
self.use_ecx(source_info, |this| {
310+
this.ecx.eval_rvalue_into_place(rvalue, place)?;
311+
this.ecx.eval_place_to_op(place, Some(place_layout))
312+
})
308313
},
309314
Rvalue::Ref(_, _, ref place) => {
310315
let src = self.eval_place(place, source_info)?;
@@ -324,22 +329,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
324329
Ok(dest.into())
325330
})
326331
},
327-
Rvalue::Len(ref place) => {
328-
let place = self.eval_place(&place, source_info)?;
329-
let mplace = place.try_as_mplace().ok()?;
330-
331-
if let ty::Slice(_) = mplace.layout.ty.kind {
332-
let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
333-
334-
Some(ImmTy::from_uint(
335-
len,
336-
self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
337-
).into())
338-
} else {
339-
trace!("not slice: {:?}", mplace.layout.ty.kind);
340-
None
341-
}
342-
},
343332
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
344333
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
345334
ImmTy::from_uint(
@@ -626,15 +615,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
626615
.ty(&self.local_decls, self.tcx)
627616
.ty;
628617
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
629-
if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) {
630-
if let Place {
631-
base: PlaceBase::Local(local),
632-
projection: box [],
633-
} = *place {
618+
if let Place {
619+
base: PlaceBase::Local(local),
620+
projection: box [],
621+
} = *place {
622+
if let Some(value) = self.const_prop(rval, place_layout, statement.source_info, place) {
634623
trace!("checking whether {:?} can be stored to {:?}", value, local);
635624
if self.can_const_prop[local] {
636625
trace!("storing {:?} to {:?}", value, local);
637-
assert!(self.get_const(local).is_none());
626+
assert!(self.get_const(local).is_none() || self.get_const(local) == Some(value));
638627
self.set_const(local, value);
639628

640629
if self.should_const_prop() {
@@ -648,6 +637,18 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
648637
}
649638
}
650639
}
640+
} else if let StatementKind::StorageLive(local) = statement.kind {
641+
if self.can_const_prop[local] {
642+
let frame = self.ecx.frame_mut();
643+
644+
frame.locals[local].value = LocalValue::Uninitialized;
645+
}
646+
} else if let StatementKind::StorageDead(local) = statement.kind {
647+
if self.can_const_prop[local] {
648+
let frame = self.ecx.frame_mut();
649+
650+
frame.locals[local].value = LocalValue::Dead;
651+
}
651652
}
652653
self.super_statement(statement, location);
653654
}

0 commit comments

Comments
 (0)