diff options
| author | Wesley Wiser <wwiser@gmail.com> | 2019-09-06 07:48:52 -0400 |
|---|---|---|
| committer | Wesley Wiser <wwiser@gmail.com> | 2019-09-27 20:11:12 -0400 |
| commit | 644d4f3ee93b49ee773b667a970a552983d5e8fa (patch) | |
| tree | 6e11b6c375f2cc9d917be63413b802357f1d2077 | |
| parent | 1c219bb34bead8b603da164dfcbb7c808ae70384 (diff) | |
| download | rust-644d4f3ee93b49ee773b667a970a552983d5e8fa.tar.gz rust-644d4f3ee93b49ee773b667a970a552983d5e8fa.zip | |
[const-prop] Replace most `UnaryOp` handling with use of `InterpCx`
| -rw-r--r-- | src/librustc_mir/transform/const_prop.rs | 45 |
1 files changed, 17 insertions, 28 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index c4633d57c23..f172071a8fb 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -325,39 +325,28 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { }, Rvalue::UnaryOp(op, ref arg) => { - let def_id = if self.tcx.is_closure(self.source.def_id()) { - self.tcx.closure_base_def_id(self.source.def_id()) - } else { - self.source.def_id() - }; - let generics = self.tcx.generics_of(def_id); - if generics.requires_monomorphization(self.tcx) { - // FIXME: can't handle code with generics - return None; - } + let overflow_check = self.tcx.sess.overflow_checks(); - let arg = self.eval_operand(arg, source_info)?; - let oflo_check = self.tcx.sess.overflow_checks(); - let val = self.use_ecx(source_info, |this| { - let prim = this.ecx.read_immediate(arg)?; - match op { - UnOp::Neg => { - // We check overflow in debug mode already - // so should only check in release mode. - if !oflo_check - && prim.layout.ty.is_signed() - && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { + self.use_ecx(source_info, |this| { + // We check overflow in debug mode already + // so should only check in release mode. + if op == UnOp::Neg && !overflow_check { + let ty = arg.ty(&this.local_decls, this.tcx); + + if ty.is_integral() { + let arg = this.ecx.eval_operand(arg, None)?; + let prim = this.ecx.read_immediate(arg)?; + // Need to do overflow check here: For actual CTFE, MIR + // generation emits code that does this before calling the op. + if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { throw_panic!(OverflowNeg) } } - UnOp::Not => { - // Cannot overflow - } } - // Now run the actual operation. - this.ecx.unary_op(op, prim) - })?; - Some(val.into()) + + this.ecx.eval_rvalue_into_place(rvalue, place)?; + this.ecx.eval_place_to_op(place, Some(place_layout)) + }) } Rvalue::CheckedBinaryOp(op, ref left, ref right) | Rvalue::BinaryOp(op, ref left, ref right) => { |
