diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-06-23 03:16:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-23 03:16:24 +0200 |
| commit | 490d820a25a37369f67a44fecf3805560835c527 (patch) | |
| tree | a607ce8da1d928410040e89a6dbe82baa09c90ca | |
| parent | 963a4805e30fd8ac297d05ed8442d8f838005769 (diff) | |
| parent | 7447bf22013b18ecb1c07dae3ac7472622803337 (diff) | |
| download | rust-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.rs | 2 | ||||
| -rw-r--r-- | src/librustc_middle/mir/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/terminator.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/transform/validate.rs | 12 |
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, |
