about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-06-23 03:16:24 +0200
committerGitHub <noreply@github.com>2020-06-23 03:16:24 +0200
commit490d820a25a37369f67a44fecf3805560835c527 (patch)
treea607ce8da1d928410040e89a6dbe82baa09c90ca
parent963a4805e30fd8ac297d05ed8442d8f838005769 (diff)
parent7447bf22013b18ecb1c07dae3ac7472622803337 (diff)
downloadrust-490d820a25a37369f67a44fecf3805560835c527.tar.gz
rust-490d820a25a37369f67a44fecf3805560835c527.zip
Rollup merge of #73586 - RalfJung:switch-ty, r=oli-obk
switch_ty is redundant

This field is redundant, but we cannot remove it currently as pretty-printing relies on it (and it does not have access to `mir::Body` to compute the type itself).

Cc @oli-obk @matthewjasper @jonas-schievink
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs2
-rw-r--r--src/librustc_middle/mir/mod.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs12
-rw-r--r--src/librustc_mir/transform/validate.rs12
4 files changed, 18 insertions, 10 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index d56c816811b..5125ce779ed 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -200,6 +200,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         targets: &Vec<mir::BasicBlock>,
     ) {
         let discr = self.codegen_operand(&mut bx, &discr);
+        // `switch_ty` is redundant, sanity-check that.
+        assert_eq!(discr.layout.ty, switch_ty);
         if targets.len() == 2 {
             // If there are two targets, emit br instead of switch
             let lltrue = helper.llblock(self, targets[0]);
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 3381b95c2a3..64976654799 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -1075,6 +1075,8 @@ pub enum TerminatorKind<'tcx> {
         discr: Operand<'tcx>,
 
         /// The type of value being tested.
+        /// This is always the same as the type of `discr`.
+        /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
         switch_ty: Ty<'tcx>,
 
         /// Possible values. The locations to branch to in each case
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 0f3fbcf8195..4681079a22d 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -24,9 +24,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
             Goto { target } => self.go_to_block(target),
 
-            SwitchInt { ref discr, ref values, ref targets, .. } => {
+            SwitchInt { ref discr, ref values, ref targets, switch_ty } => {
                 let discr = self.read_immediate(self.eval_operand(discr, None)?)?;
                 trace!("SwitchInt({:?})", *discr);
+                assert_eq!(discr.layout.ty, switch_ty);
 
                 // Branch to the `otherwise` case by default, if no match is found.
                 assert!(!targets.is_empty());
@@ -50,14 +51,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.go_to_block(target_block);
             }
 
-            Call {
-                ref func,
-                ref args,
-                destination,
-                ref cleanup,
-                from_hir_call: _from_hir_call,
-                fn_span: _,
-            } => {
+            Call { ref func, ref args, destination, ref cleanup, from_hir_call: _, fn_span: _ } => {
                 let old_stack = self.frame_idx();
                 let old_loc = self.frame().loc;
                 let func = self.eval_operand(func, None)?;
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index 953b335d9d7..c5343d9b5d0 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -121,7 +121,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             TerminatorKind::Goto { target } => {
                 self.check_edge(location, *target, EdgeKind::Normal);
             }
-            TerminatorKind::SwitchInt { targets, values, .. } => {
+            TerminatorKind::SwitchInt { targets, values, switch_ty, discr } => {
+                let ty = discr.ty(&self.body.local_decls, self.tcx);
+                if ty != *switch_ty {
+                    self.fail(
+                        location,
+                        format!(
+                            "encountered `SwitchInt` terminator with type mismatch: {:?} != {:?}",
+                            ty, switch_ty,
+                        ),
+                    );
+                }
                 if targets.len() != values.len() + 1 {
                     self.fail(
                         location,