parent
10ab168db9
commit
d6f1ba89ce
3 changed files with 34 additions and 16 deletions
|
@ -1,5 +1,4 @@
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
|
@ -45,26 +44,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
SwitchInt { ref discr, ref values, ref targets, .. } => {
|
||||
let discr_ptr = self.eval_lvalue(discr)?.to_ptr();
|
||||
let discr_ty = self.lvalue_ty(discr);
|
||||
let discr_size = self
|
||||
.type_layout(discr_ty)
|
||||
.size(&self.tcx.data_layout)
|
||||
.bytes() as usize;
|
||||
let discr_val = self.memory.read_uint(discr_ptr, discr_size)?;
|
||||
if let ty::TyChar = discr_ty.sty {
|
||||
if ::std::char::from_u32(discr_val as u32).is_none() {
|
||||
return Err(EvalError::InvalidChar(discr_val as u64));
|
||||
}
|
||||
}
|
||||
let discr_val = self.read_value(discr_ptr, discr_ty)?;
|
||||
let discr_prim = self.value_to_primval(discr_val, discr_ty)?;
|
||||
|
||||
// Branch to the `otherwise` case by default, if no match is found.
|
||||
let mut target_block = targets[targets.len() - 1];
|
||||
|
||||
for (index, const_val) in values.iter().enumerate() {
|
||||
let val = match const_val {
|
||||
&ConstVal::Integral(i) => i.to_u64_unchecked(),
|
||||
_ => bug!("TerminatorKind::SwitchInt branch constant was not an integer"),
|
||||
};
|
||||
if discr_val == val {
|
||||
let val = self.const_to_value(const_val)?;
|
||||
let prim = self.value_to_primval(val, discr_ty)?;
|
||||
if discr_prim == prim {
|
||||
target_block = targets[index];
|
||||
break;
|
||||
}
|
||||
|
|
8
tests/run-pass/match_slice.rs
Normal file
8
tests/run-pass/match_slice.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
fn main() {
|
||||
let x = "hello";
|
||||
match x {
|
||||
"foo" => {},
|
||||
"bar" => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
21
tests/run-pass/rust-lang-org.rs
Normal file
21
tests/run-pass/rust-lang-org.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// This code is editable and runnable!
|
||||
fn main() {
|
||||
// A simple integer calculator:
|
||||
// `+` or `-` means add or subtract by 1
|
||||
// `*` or `/` means multiply or divide by 2
|
||||
|
||||
let program = "+ + * - /";
|
||||
let mut accumulator = 0;
|
||||
|
||||
for token in program.chars() {
|
||||
match token {
|
||||
'+' => accumulator += 1,
|
||||
'-' => accumulator -= 1,
|
||||
'*' => accumulator *= 2,
|
||||
'/' => accumulator /= 2,
|
||||
_ => { /* ignore everything else */ }
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(accumulator, 1);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue