Skip to content

Commit 79bf586

Browse files
committed
switch to BitVector, simplify target_block logic
clarify comments and panic message
1 parent 9d34c28 commit 79bf586

File tree

3 files changed

+25
-27
lines changed

3 files changed

+25
-27
lines changed

src/librustc_data_structures/bitvec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use std::iter::FromIterator;
1212

1313
/// A very simple BitVector type.
14-
#[derive(Clone)]
14+
#[derive(Clone, Debug, PartialEq)]
1515
pub struct BitVector {
1616
data: Vec<u64>,
1717
}

src/librustc_mir/build/matches/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
1616
use build::{BlockAnd, BlockAndExtension, Builder};
1717
use rustc_data_structures::fnv::FnvHashMap;
18+
use rustc_data_structures::bitvec::BitVector;
1819
use rustc::middle::const_val::ConstVal;
1920
use rustc::ty::{AdtDef, Ty};
2021
use rustc::mir::repr::*;
@@ -266,7 +267,7 @@ enum TestKind<'tcx> {
266267
// test the branches of enum
267268
Switch {
268269
adt_def: AdtDef<'tcx>,
269-
variants: Vec<bool>,
270+
variants: BitVector,
270271
},
271272

272273
// test the branches of enum

src/librustc_mir/build/matches/test.rs

+22-25
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use build::Builder;
1919
use build::matches::{Candidate, MatchPair, Test, TestKind};
2020
use hair::*;
2121
use rustc_data_structures::fnv::FnvHashMap;
22+
use rustc_data_structures::bitvec::BitVector;
2223
use rustc::middle::const_val::ConstVal;
2324
use rustc::ty::{self, Ty};
2425
use rustc::mir::repr::*;
@@ -35,7 +36,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
3536
span: match_pair.pattern.span,
3637
kind: TestKind::Switch {
3738
adt_def: adt_def.clone(),
38-
variants: vec![false; self.hir.num_variants(adt_def)],
39+
variants: BitVector::new(self.hir.num_variants(adt_def)),
3940
},
4041
}
4142
}
@@ -129,7 +130,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
129130
true
130131
}
131132
PatternKind::Variant { .. } => {
132-
panic!("you should have called add_cases_to_switch_switch instead!");
133+
panic!("you should have called add_variants_to_switch instead!");
133134
}
134135
PatternKind::Range { .. } |
135136
PatternKind::Slice { .. } |
@@ -145,10 +146,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
145146
}
146147

147148
pub fn add_variants_to_switch<'pat>(&mut self,
148-
test_lvalue: &Lvalue<'tcx>,
149-
candidate: &Candidate<'pat, 'tcx>,
150-
variants: &mut Vec<bool>)
151-
-> bool
149+
test_lvalue: &Lvalue<'tcx>,
150+
candidate: &Candidate<'pat, 'tcx>,
151+
variants: &mut BitVector)
152+
-> bool
152153
{
153154
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.lvalue == *test_lvalue) {
154155
Some(match_pair) => match_pair,
@@ -157,8 +158,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
157158

158159
match *match_pair.pattern.kind {
159160
PatternKind::Variant { adt_def: _ , variant_index, .. } => {
160-
// Do I need to look at the PatternKind::Variant subpatterns?
161-
variants[variant_index] |= true;
161+
// We have a pattern testing for variant `variant_index`
162+
// set the corresponding index to true
163+
variants.insert(variant_index);
162164
true
163165
}
164166
_ => {
@@ -178,24 +180,19 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
178180
match test.kind {
179181
TestKind::Switch { adt_def, ref variants } => {
180182
let num_enum_variants = self.hir.num_variants(adt_def);
181-
debug!("num_enum_variants: {}", num_enum_variants);
182-
debug!("variants.len(): {}", variants.len());
183-
debug!("variants: {:?}", variants);
184-
let target_blocks: Vec<_> = if variants.into_iter().any(|b| {!b}) {
185-
let otherwise_block = self.cfg.start_new_block();
186-
debug!("basic block: {:?} is an otherwise block!", otherwise_block);
187-
(0..num_enum_variants).map(|i|
188-
if variants[i] {
189-
self.cfg.start_new_block()
190-
} else {
191-
otherwise_block
183+
let mut otherwise_block = None;
184+
let target_blocks: Vec<_> = (0..num_enum_variants).map(|i| {
185+
if variants.contains(i) {
186+
self.cfg.start_new_block()
187+
} else {
188+
if otherwise_block.is_none() {
189+
otherwise_block = Some(self.cfg.start_new_block());
192190
}
193-
)
194-
.collect()
195-
} else {
196-
(0..num_enum_variants).map(|_| self.cfg.start_new_block())
197-
.collect()
198-
};
191+
otherwise_block.unwrap()
192+
}
193+
}).collect();
194+
debug!("num_enum_variants: {}, num tested variants: {}, variants: {:?}",
195+
num_enum_variants, variants.iter().count(), variants);
199196
self.cfg.terminate(block, scope_id, test.span, TerminatorKind::Switch {
200197
discr: lvalue.clone(),
201198
adt_def: adt_def,

0 commit comments

Comments
 (0)