Skip to content

Commit 644d4f3

Browse files
committed
[const-prop] Replace most UnaryOp handling with use of InterpCx
1 parent 1c219bb commit 644d4f3

File tree

1 file changed

+17
-28
lines changed

1 file changed

+17
-28
lines changed

src/librustc_mir/transform/const_prop.rs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -325,39 +325,28 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
325325
},
326326

327327
Rvalue::UnaryOp(op, ref arg) => {
328-
let def_id = if self.tcx.is_closure(self.source.def_id()) {
329-
self.tcx.closure_base_def_id(self.source.def_id())
330-
} else {
331-
self.source.def_id()
332-
};
333-
let generics = self.tcx.generics_of(def_id);
334-
if generics.requires_monomorphization(self.tcx) {
335-
// FIXME: can't handle code with generics
336-
return None;
337-
}
328+
let overflow_check = self.tcx.sess.overflow_checks();
338329

339-
let arg = self.eval_operand(arg, source_info)?;
340-
let oflo_check = self.tcx.sess.overflow_checks();
341-
let val = self.use_ecx(source_info, |this| {
342-
let prim = this.ecx.read_immediate(arg)?;
343-
match op {
344-
UnOp::Neg => {
345-
// We check overflow in debug mode already
346-
// so should only check in release mode.
347-
if !oflo_check
348-
&& prim.layout.ty.is_signed()
349-
&& prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
330+
self.use_ecx(source_info, |this| {
331+
// We check overflow in debug mode already
332+
// so should only check in release mode.
333+
if op == UnOp::Neg && !overflow_check {
334+
let ty = arg.ty(&this.local_decls, this.tcx);
335+
336+
if ty.is_integral() {
337+
let arg = this.ecx.eval_operand(arg, None)?;
338+
let prim = this.ecx.read_immediate(arg)?;
339+
// Need to do overflow check here: For actual CTFE, MIR
340+
// generation emits code that does this before calling the op.
341+
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
350342
throw_panic!(OverflowNeg)
351343
}
352344
}
353-
UnOp::Not => {
354-
// Cannot overflow
355-
}
356345
}
357-
// Now run the actual operation.
358-
this.ecx.unary_op(op, prim)
359-
})?;
360-
Some(val.into())
346+
347+
this.ecx.eval_rvalue_into_place(rvalue, place)?;
348+
this.ecx.eval_place_to_op(place, Some(place_layout))
349+
})
361350
}
362351
Rvalue::CheckedBinaryOp(op, ref left, ref right) |
363352
Rvalue::BinaryOp(op, ref left, ref right) => {

0 commit comments

Comments
 (0)