From 3bfd0c9f0725b8fb096ea38446b4dcc2a3f90980 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jun 2020 18:22:30 +0200 Subject: [PATCH 1/3] remove switch_ty reliance in codegen --- src/librustc_codegen_ssa/mir/block.rs | 2 ++ src/librustc_middle/mir/mod.rs | 2 ++ src/librustc_mir/interpret/terminator.rs | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d56c816811b3c..5125ce779ed8e 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, ) { 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 3381b95c2a38e..649766547990f 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 1d57fce39734e..a3cb450ff2860 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()); @@ -55,7 +56,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ref args, destination, ref cleanup, - from_hir_call: _from_hir_call, + from_hir_call: _, fn_span: _, } => { let old_stack = self.frame_idx(); From 629722893cd39bcf9929b56b50ef5476f1d22a55 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jun 2020 18:24:51 +0200 Subject: [PATCH 2/3] MIR validation: check switch_ty --- src/librustc_mir/transform/validate.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs index 625f40cd79206..18744ef3d7241 100644 --- a/src/librustc_mir/transform/validate.rs +++ b/src/librustc_mir/transform/validate.rs @@ -121,7 +121,18 @@ 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, From 7447bf22013b18ecb1c07dae3ac7472622803337 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jun 2020 19:35:57 +0200 Subject: [PATCH 3/3] fmt --- src/librustc_mir/interpret/terminator.rs | 9 +-------- src/librustc_mir/transform/validate.rs | 3 +-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index a3cb450ff2860..82fcf6f1d2c31 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -51,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: _, - 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 18744ef3d7241..369ab1b274209 100644 --- a/src/librustc_mir/transform/validate.rs +++ b/src/librustc_mir/transform/validate.rs @@ -128,8 +128,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { location, format!( "encountered `SwitchInt` terminator with type mismatch: {:?} != {:?}", - ty, - switch_ty, + ty, switch_ty, ), ); }