|
15 | 15 |
|
16 | 16 | use build::{BlockAnd, Builder};
|
17 | 17 | use repr::*;
|
| 18 | +use rustc_data_structures::fnv::FnvHashMap; |
| 19 | +use rustc::middle::const_eval::ConstVal; |
18 | 20 | use rustc::middle::region::CodeExtent;
|
19 | 21 | use rustc::middle::ty::{AdtDef, Ty};
|
20 | 22 | use hair::*;
|
@@ -241,6 +243,13 @@ enum TestKind<'tcx> {
|
241 | 243 | adt_def: AdtDef<'tcx>,
|
242 | 244 | },
|
243 | 245 |
|
| 246 | + // test the branches of enum |
| 247 | + SwitchInt { |
| 248 | + switch_ty: Ty<'tcx>, |
| 249 | + options: Vec<ConstVal>, |
| 250 | + indices: FnvHashMap<ConstVal, usize>, |
| 251 | + }, |
| 252 | + |
244 | 253 | // test for equality
|
245 | 254 | Eq {
|
246 | 255 | value: Literal<'tcx>,
|
@@ -315,20 +324,36 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|
315 | 324 |
|
316 | 325 | // otherwise, extract the next match pair and construct tests
|
317 | 326 | let match_pair = &candidates.last().unwrap().match_pairs[0];
|
318 |
| - let test = self.test(match_pair); |
| 327 | + let mut test = self.test(match_pair); |
| 328 | + |
| 329 | + // most of the time, the test to perform is simply a function |
| 330 | + // of the main candidate; but for a test like SwitchInt, we |
| 331 | + // may want to add cases based on the candidates that are |
| 332 | + // available |
| 333 | + match test.kind { |
| 334 | + TestKind::SwitchInt { switch_ty, ref mut options, ref mut indices } => { |
| 335 | + for candidate in &candidates { |
| 336 | + self.add_cases_to_switch(&match_pair.lvalue, |
| 337 | + candidate, |
| 338 | + switch_ty, |
| 339 | + options, |
| 340 | + indices); |
| 341 | + } |
| 342 | + } |
| 343 | + _ => { } |
| 344 | + } |
| 345 | + |
319 | 346 | debug!("match_candidates: test={:?} match_pair={:?}", test, match_pair);
|
320 | 347 | let target_blocks = self.perform_test(block, &match_pair.lvalue, &test);
|
321 | 348 |
|
322 |
| - for (outcome, mut target_block) in target_blocks.into_iter().enumerate() { |
| 349 | + for (outcome, target_block) in target_blocks.into_iter().enumerate() { |
323 | 350 | let applicable_candidates: Vec<Candidate<'tcx>> =
|
324 | 351 | candidates.iter()
|
325 | 352 | .filter_map(|candidate| {
|
326 |
| - unpack!(target_block = |
327 |
| - self.candidate_under_assumption(target_block, |
328 |
| - &match_pair.lvalue, |
329 |
| - &test.kind, |
330 |
| - outcome, |
331 |
| - candidate)) |
| 353 | + self.candidate_under_assumption(&match_pair.lvalue, |
| 354 | + &test.kind, |
| 355 | + outcome, |
| 356 | + candidate) |
332 | 357 | })
|
333 | 358 | .collect();
|
334 | 359 | self.match_candidates(span, arm_blocks, applicable_candidates, target_block);
|
|
0 commit comments