Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_middle/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to be more aggressive about it you can #[deprecate] it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what that would help with?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would nudge people away from new usages of this field.

switch_ty: Ty<'tcx>,

/// Possible values. The locations to branch to in each case
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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();
Expand Down
13 changes: 12 additions & 1 deletion src/librustc_mir/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down