Skip to content

Commit d6f1ba8

Browse files
committed
fix matching on chars
fixes rust-lang#63
1 parent 10ab168 commit d6f1ba8

File tree

3 files changed

+34
-16
lines changed

3 files changed

+34
-16
lines changed

src/interpreter/terminator/mod.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rustc::hir::def_id::DefId;
2-
use rustc::middle::const_val::ConstVal;
32
use rustc::mir::repr as mir;
43
use rustc::traits::{self, Reveal};
54
use rustc::ty::fold::TypeFoldable;
@@ -45,26 +44,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
4544
SwitchInt { ref discr, ref values, ref targets, .. } => {
4645
let discr_ptr = self.eval_lvalue(discr)?.to_ptr();
4746
let discr_ty = self.lvalue_ty(discr);
48-
let discr_size = self
49-
.type_layout(discr_ty)
50-
.size(&self.tcx.data_layout)
51-
.bytes() as usize;
52-
let discr_val = self.memory.read_uint(discr_ptr, discr_size)?;
53-
if let ty::TyChar = discr_ty.sty {
54-
if ::std::char::from_u32(discr_val as u32).is_none() {
55-
return Err(EvalError::InvalidChar(discr_val as u64));
56-
}
57-
}
47+
let discr_val = self.read_value(discr_ptr, discr_ty)?;
48+
let discr_prim = self.value_to_primval(discr_val, discr_ty)?;
5849

5950
// Branch to the `otherwise` case by default, if no match is found.
6051
let mut target_block = targets[targets.len() - 1];
6152

6253
for (index, const_val) in values.iter().enumerate() {
63-
let val = match const_val {
64-
&ConstVal::Integral(i) => i.to_u64_unchecked(),
65-
_ => bug!("TerminatorKind::SwitchInt branch constant was not an integer"),
66-
};
67-
if discr_val == val {
54+
let val = self.const_to_value(const_val)?;
55+
let prim = self.value_to_primval(val, discr_ty)?;
56+
if discr_prim == prim {
6857
target_block = targets[index];
6958
break;
7059
}

tests/run-pass/match_slice.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let x = "hello";
3+
match x {
4+
"foo" => {},
5+
"bar" => {},
6+
_ => {},
7+
}
8+
}

tests/run-pass/rust-lang-org.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This code is editable and runnable!
2+
fn main() {
3+
// A simple integer calculator:
4+
// `+` or `-` means add or subtract by 1
5+
// `*` or `/` means multiply or divide by 2
6+
7+
let program = "+ + * - /";
8+
let mut accumulator = 0;
9+
10+
for token in program.chars() {
11+
match token {
12+
'+' => accumulator += 1,
13+
'-' => accumulator -= 1,
14+
'*' => accumulator *= 2,
15+
'/' => accumulator /= 2,
16+
_ => { /* ignore everything else */ }
17+
}
18+
}
19+
20+
assert_eq!(accumulator, 1);
21+
}

0 commit comments

Comments
 (0)