about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2019-09-15 12:08:09 -0400
committerWesley Wiser <wwiser@gmail.com>2019-10-18 19:16:49 -0400
commit8cf6c23d66ce4d80d6d76291c10cbbe6cab9cb00 (patch)
treeacb4021104b2da9e2db919ead51378edcff1f2e8
parent2d22063e4c6fbdb61ce2a2dd9ce50d12fe9f0e9b (diff)
Cleanup const_prop() some
-rw-r--r--src/librustc_mir/transform/const_prop.rs147
1 files changed, 75 insertions, 72 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 984938d00b2..abb880fd624 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -118,7 +118,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
 struct ConstPropMachine;
 
 impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
-    type MemoryKinds= !;
+    type MemoryKinds = !;
     type PointerTag = ();
     type ExtraFnVal = !;
 
@@ -435,79 +435,80 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let span = source_info.span;
 
         // perform any special checking for specific Rvalue types
-        if let Rvalue::UnaryOp(op, arg) = rvalue {
-            trace!("checking UnaryOp(op = {:?}, arg = {:?})", op, arg);
-            let overflow_check = self.tcx.sess.overflow_checks();
-
-            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)
+        match rvalue {
+            Rvalue::UnaryOp(UnOp::Neg, arg) => {
+                trace!("checking UnaryOp(op = Neg, arg = {:?})", arg);
+                let overflow_check = self.tcx.sess.overflow_checks();
+
+                self.use_ecx(source_info, |this| {
+                    // We check overflow in debug mode already
+                    // so should only check in release mode.
+                    if !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)
+                            }
                         }
                     }
-                }
 
-                Ok(())
-            })?;
-        } else if let Rvalue::BinaryOp(op, left, right) = rvalue {
-            trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
-
-            let r = self.use_ecx(source_info, |this| {
-                this.ecx.read_immediate(this.ecx.eval_operand(right, None)?)
-            })?;
-            if *op == BinOp::Shr || *op == BinOp::Shl {
-                let left_bits = place_layout.size.bits();
-                let right_size = r.layout.size;
-                let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
-                if r_bits.ok().map_or(false, |b| b >= left_bits as u128) {
-                    let source_scope_local_data = match self.source_scope_local_data {
-                        ClearCrossCrate::Set(ref data) => data,
-                        ClearCrossCrate::Clear => return None,
-                    };
-                    let dir = if *op == BinOp::Shr {
-                        "right"
-                    } else {
-                        "left"
-                    };
-                    let hir_id = source_scope_local_data[source_info.scope].lint_root;
-                    self.tcx.lint_hir(
-                        ::rustc::lint::builtin::EXCEEDING_BITSHIFTS,
-                        hir_id,
-                        span,
-                        &format!("attempt to shift {} with overflow", dir));
-                    return None;
-                }
+                    Ok(())
+                })?;
             }
-            self.use_ecx(source_info, |this| {
-                let l = this.ecx.read_immediate(this.ecx.eval_operand(left, None)?)?;
-                let (_, overflow, _ty) = this.ecx.overflowing_binary_op(*op, l, r)?;
-
-                // We check overflow in debug mode already
-                // so should only check in release mode.
-                if !this.tcx.sess.overflow_checks() && overflow {
-                    let err = err_panic!(Overflow(*op)).into();
-                    return Err(err);
+
+            Rvalue::BinaryOp(op, left, right) => {
+                trace!("checking BinaryOp(op = {:?}, left = {:?}, right = {:?})", op, left, right);
+
+                let r = self.use_ecx(source_info, |this| {
+                    this.ecx.read_immediate(this.ecx.eval_operand(right, None)?)
+                })?;
+                if *op == BinOp::Shr || *op == BinOp::Shl {
+                    let left_bits = place_layout.size.bits();
+                    let right_size = r.layout.size;
+                    let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
+                    if r_bits.ok().map_or(false, |b| b >= left_bits as u128) {
+                        let source_scope_local_data = match self.source_scope_local_data {
+                            ClearCrossCrate::Set(ref data) => data,
+                            ClearCrossCrate::Clear => return None,
+                        };
+                        let dir = if *op == BinOp::Shr {
+                            "right"
+                        } else {
+                            "left"
+                        };
+                        let hir_id = source_scope_local_data[source_info.scope].lint_root;
+                        self.tcx.lint_hir(
+                            ::rustc::lint::builtin::EXCEEDING_BITSHIFTS,
+                            hir_id,
+                            span,
+                            &format!("attempt to shift {} with overflow", dir));
+                        return None;
+                    }
                 }
+                self.use_ecx(source_info, |this| {
+                    let l = this.ecx.read_immediate(this.ecx.eval_operand(left, None)?)?;
+                    let (_, overflow, _ty) = this.ecx.overflowing_binary_op(*op, l, r)?;
+
+                    // We check overflow in debug mode already
+                    // so should only check in release mode.
+                    if !this.tcx.sess.overflow_checks() && overflow {
+                        let err = err_panic!(Overflow(*op)).into();
+                        return Err(err);
+                    }
 
-                Ok(())
-            })?;
-        } else if let Rvalue::Ref(_, _, place) = rvalue {
-            trace!("checking Ref({:?})", place);
-            // FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
-            // from a function argument that hasn't been assigned to in this function.
-            if let Place {
-                base: PlaceBase::Local(local),
-                projection: box []
-            } = place {
+                    Ok(())
+                })?;
+            }
+
+            Rvalue::Ref(_, _, Place { base: PlaceBase::Local(local), projection: box [] }) => {
+                trace!("checking Ref({:?})", place);
+                // FIXME(wesleywiser) we don't currently handle the case where we try to make a ref
+                // from a function argument that hasn't been assigned to in this function.
                 let alive =
                     if let LocalValue::Live(_) = self.ecx.frame().locals[*local].value {
                         true
@@ -518,12 +519,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     return None;
                 }
             }
-        } else if let Rvalue::Aggregate(_, operands) = rvalue {
-            // FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
-            // `SimplifyLocals` doesn't know it can remove.
-            if operands.len() == 0 {
+
+            Rvalue::Aggregate(_, operands) if operands.len() == 0 => {
+                // FIXME(wesleywiser): const eval will turn this into a `const Scalar(<ZST>)` that
+                // `SimplifyLocals` doesn't know it can remove.
                 return None;
             }
+
+            _ => { }
         }
 
         self.use_ecx(source_info, |this| {