about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-12-28 22:44:04 +0100
committerRalf Jung <post@ralfj.de>2020-12-28 22:44:04 +0100
commitc177e68015c0915aee333540f29d1673fe6ffdd5 (patch)
tree910eb975a622ea48c8c9fc6f8cc1537e0e10a2df
parent122e91c4fbba35a2331647f89a4f49e668e0cd88 (diff)
downloadrust-c177e68015c0915aee333540f29d1673fe6ffdd5.tar.gz
rust-c177e68015c0915aee333540f29d1673fe6ffdd5.zip
merge two match'es for more exhaustiveness
-rw-r--r--compiler/rustc_mir/src/transform/promote_consts.rs80
1 files changed, 41 insertions, 39 deletions
diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs
index 6791d7b1ba0..7cb80c78c8d 100644
--- a/compiler/rustc_mir/src/transform/promote_consts.rs
+++ b/compiler/rustc_mir/src/transform/promote_consts.rs
@@ -90,7 +90,7 @@ pub enum TempState {
 impl TempState {
     pub fn is_promotable(&self) -> bool {
         debug!("is_promotable: self={:?}", self);
-        matches!(self, TempState::Defined { .. } )
+        matches!(self, TempState::Defined { .. })
     }
 }
 
@@ -329,7 +329,6 @@ impl<'tcx> Validator<'_, 'tcx> {
                             return Err(Unpromotable);
                         }
 
-
                         Ok(())
                     }
                     _ => bug!(),
@@ -583,18 +582,33 @@ impl<'tcx> Validator<'_, 'tcx> {
     }
 
     fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
-        match *rvalue {
-            Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
-                let operand_ty = operand.ty(self.body, self.tcx);
-                let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
-                let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
-                if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
-                    // ptr-to-int casts are not possible in consts and thus not promotable
-                    return Err(Unpromotable);
+        match rvalue {
+            Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_, operand) => {
+                self.validate_operand(operand)?;
+            }
+
+            Rvalue::Discriminant(place) | Rvalue::Len(place) => self.validate_place(place.as_ref())?,
+
+            Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
+
+            Rvalue::Cast(kind, operand, cast_ty) => {
+                if matches!(kind, CastKind::Misc) {
+                    let operand_ty = operand.ty(self.body, self.tcx);
+                    let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
+                    let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
+                    if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
+                        // ptr-to-int casts are not possible in consts and thus not promotable
+                        return Err(Unpromotable);
+                    }
+                    // int-to-ptr casts are fine, they just use the integer value at pointer type.
                 }
+
+                self.validate_operand(operand)?;
             }
 
-            Rvalue::BinaryOp(op, ref lhs, _) => {
+            Rvalue::BinaryOp(op, lhs, rhs)
+            | Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
+                let op = *op;
                 if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind() {
                     assert!(
                         op == BinOp::Eq
@@ -609,29 +623,17 @@ impl<'tcx> Validator<'_, 'tcx> {
                     // raw pointer operations are not allowed inside consts and thus not promotable
                     return Err(Unpromotable);
                 }
-            }
-
-            Rvalue::NullaryOp(NullOp::Box, _) => return Err(Unpromotable),
-
-            // FIXME(RalfJung): the rest is *implicitly considered promotable*... that seems dangerous.
-            _ => {}
-        }
-
-        match rvalue {
-            Rvalue::ThreadLocalRef(_) => Err(Unpromotable),
-
-            Rvalue::NullaryOp(..) => Ok(()),
 
-            Rvalue::Discriminant(place) | Rvalue::Len(place) => self.validate_place(place.as_ref()),
+                // FIXME: reject operations that can fail -- namely, division and modulo.
 
-            Rvalue::Use(operand)
-            | Rvalue::Repeat(operand, _)
-            | Rvalue::UnaryOp(_, operand)
-            | Rvalue::Cast(_, operand, _) => self.validate_operand(operand),
-
-            Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
                 self.validate_operand(lhs)?;
-                self.validate_operand(rhs)
+                self.validate_operand(rhs)?;
+            }
+
+            Rvalue::NullaryOp(op, _) => {
+                if matches!(op, NullOp::Box) {
+                    return Err(Unpromotable);
+                }
             }
 
             Rvalue::AddressOf(_, place) => {
@@ -646,16 +648,18 @@ impl<'tcx> Validator<'_, 'tcx> {
                         });
                     }
                 }
-                Err(Unpromotable)
+                return Err(Unpromotable);
             }
 
             Rvalue::Ref(_, kind, place) => {
                 // Special-case reborrows to be more like a copy of the reference.
                 let mut place_simplified = place.as_ref();
                 if let [proj_base @ .., ProjectionElem::Deref] = &place_simplified.projection {
-                    let base_ty = Place::ty_from(place_simplified.local, proj_base, self.body, self.tcx).ty;
+                    let base_ty =
+                        Place::ty_from(place_simplified.local, proj_base, self.body, self.tcx).ty;
                     if let ty::Ref(..) = base_ty.kind() {
-                        place_simplified = PlaceRef { local: place_simplified.local, projection: proj_base };
+                        place_simplified =
+                            PlaceRef { local: place_simplified.local, projection: proj_base };
                     }
                 }
 
@@ -664,18 +668,16 @@ impl<'tcx> Validator<'_, 'tcx> {
                 // Check that the reference is fine (using the original place!).
                 // (Needs to come after `validate_local` to avoid ICEs.)
                 self.validate_ref(*kind, place)?;
-
-                Ok(())
             }
 
-            Rvalue::Aggregate(_, ref operands) => {
+            Rvalue::Aggregate(_, operands) => {
                 for o in operands {
                     self.validate_operand(o)?;
                 }
-
-                Ok(())
             }
         }
+
+        Ok(())
     }
 
     fn validate_call(