1
Fork 0

Remove bitslice.rs.

This requires the following changes.

- It moves parts of bitslice.rs into bitvec.rs: `bitwise()`,
  `BitwiseOperator`, `bits_to_string()`.

- It changes `IdxSet` to just be a wrapper around `BitArray`.

- It changes `BitArray` and `BitVec` to use `usize` words instead of
  `u128` words. (`BitSlice` and `IdxSet` already use `usize`.) Local
  profiling showed `usize` was better.

- It moves some operations from `IdxSet` into `BitArray`:
  `new_filled()`, `clear()`, `set_up_to()`, `trim_to()` (renamed
  `clear_above()`), `words()` and `words_mut()`, `encode()` and
  `decode(). The `IdxSet` operations now just call the `BitArray`
  operations.

- It replaces `BitArray`'s iterator implementation with `IdxSet`'s,
  because the latter is more concise. It also removes the buggy
  `size_hint` function from `BitArray`'s iterator, which counted the
  number of *words* rather than the number of *bits*. `IdxSet`'s
  iterator is now just a thin wrapper around `BitArray`'s iterator.

- It moves some unit tests from `indexed_set.rs` to `bitvec.rs`.
This commit is contained in:
Nicholas Nethercote 2018-09-13 14:19:01 +10:00
parent 755fcae75e
commit b697409f10
8 changed files with 225 additions and 321 deletions

View file

@ -1,146 +0,0 @@
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME: merge with `bitvec`
use std::mem;
pub type Word = usize;
/// `BitSlice` provides helper methods for treating a `[Word]`
/// as a bitvector.
pub trait BitSlice {
fn clear_bit(&mut self, idx: usize) -> bool;
fn set_bit(&mut self, idx: usize) -> bool;
fn get_bit(&self, idx: usize) -> bool;
}
impl BitSlice for [Word] {
/// Clears bit at `idx` to 0; returns true iff this changed `self.`
#[inline]
fn clear_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("clear_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask=0x{:x}", word, bit_in_word, bit_mask);
let oldv = words[word];
let newv = oldv & !bit_mask;
words[word] = newv;
oldv != newv
}
/// Sets bit at `idx` to 1; returns true iff this changed `self.`
#[inline]
fn set_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("set_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
let oldv = words[word];
let newv = oldv | bit_mask;
words[word] = newv;
oldv != newv
}
/// Extracts value of bit at `idx` in `self`.
#[inline]
fn get_bit(&self, idx: usize) -> bool {
let words = self;
let BitLookup { word, bit_mask, .. } = bit_lookup(idx);
(words[word] & bit_mask) != 0
}
}
struct BitLookup {
/// An index of the word holding the bit in original `[Word]` of query.
word: usize,
/// Index of the particular bit within the word holding the bit.
bit_in_word: usize,
/// Word with single 1-bit set corresponding to where the bit is located.
bit_mask: Word,
}
#[inline]
fn bit_lookup(bit: usize) -> BitLookup {
let word_bits = mem::size_of::<Word>() * 8;
let word = bit / word_bits;
let bit_in_word = bit % word_bits;
let bit_mask = 1 << bit_in_word;
BitLookup { word, bit_in_word, bit_mask }
}
pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut result = String::new();
let mut sep = '[';
// Note: this is a little endian printout of bytes.
// i tracks how many bits we have printed so far.
let mut i = 0;
for &word in words.iter() {
let mut v = word;
for _ in 0..mem::size_of::<Word>() { // for each byte in `v`:
let remain = bits - i;
// If less than a byte remains, then mask just that many bits.
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
assert!(mask <= 0xFF);
let byte = v & mask;
result.push_str(&format!("{}{:02x}", sep, byte));
if remain <= 8 { break; }
v >>= 8;
i += 8;
sep = '-';
}
sep = '|';
}
result.push(']');
result
}
#[inline]
pub fn bitwise<Op:BitwiseOperator>(out_vec: &mut [Word],
in_vec: &[Word],
op: &Op) -> bool {
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
for (out_elt, in_elt) in out_vec.iter_mut().zip(in_vec) {
let old_val = *out_elt;
let new_val = op.join(old_val, *in_elt);
*out_elt = new_val;
changed |= old_val != new_val;
}
changed
}
pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: Word, pred2: Word) -> Word;
}
pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}

View file

@ -9,15 +9,19 @@
// except according to those terms.
use indexed_vec::{Idx, IndexVec};
use rustc_serialize;
use std::iter;
use std::marker::PhantomData;
use std::slice;
type Word = u128;
const WORD_BITS: usize = 128;
pub type Word = u64;
pub const WORD_BYTES: usize = ::std::mem::size_of::<Word>();
pub const WORD_BITS: usize = WORD_BYTES * 8;
/// A very simple BitArray type.
///
/// It does not support resizing after creation; use `BitVector` for that.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BitArray<C: Idx> {
data: Vec<Word>,
marker: PhantomData<C>,
@ -27,7 +31,7 @@ impl<C: Idx> BitArray<C> {
// Do not make this method public, instead switch your use case to BitVector.
#[inline]
fn grow(&mut self, num_bits: C) {
let num_words = words(num_bits);
let num_words = num_words(num_bits);
if self.data.len() <= num_words {
self.data.resize(num_words + 1, 0)
}
@ -35,13 +39,29 @@ impl<C: Idx> BitArray<C> {
#[inline]
pub fn new(num_bits: usize) -> BitArray<C> {
let num_words = words(num_bits);
BitArray::new_empty(num_bits)
}
#[inline]
pub fn new_empty(num_bits: usize) -> BitArray<C> {
let num_words = num_words(num_bits);
BitArray {
data: vec![0; num_words],
marker: PhantomData,
}
}
#[inline]
pub fn new_filled(num_bits: usize) -> BitArray<C> {
let num_words = num_words(num_bits);
let mut result = BitArray {
data: vec![!0; num_words],
marker: PhantomData,
};
result.clear_above(num_bits);
result
}
#[inline]
pub fn clear(&mut self) {
for p in &mut self.data {
@ -49,6 +69,31 @@ impl<C: Idx> BitArray<C> {
}
}
/// Sets all elements up to `num_bits`.
pub fn set_up_to(&mut self, num_bits: usize) {
for p in &mut self.data {
*p = !0;
}
self.clear_above(num_bits);
}
/// Clear all elements above `num_bits`.
fn clear_above(&mut self, num_bits: usize) {
let first_clear_block = num_bits / WORD_BITS;
if first_clear_block < self.data.len() {
// Within `first_clear_block`, the `num_bits % WORD_BITS` LSBs
// should remain.
let mask = (1 << (num_bits % WORD_BITS)) - 1;
self.data[first_clear_block] &= mask;
// All the blocks above `first_clear_block` are fully cleared.
for b in &mut self.data[first_clear_block + 1..] {
*b = 0;
}
}
}
pub fn count(&self) -> usize {
self.data.iter().map(|e| e.count_ones() as usize).sum()
}
@ -88,7 +133,7 @@ impl<C: Idx> BitArray<C> {
/// Sets all bits to true.
pub fn insert_all(&mut self) {
for data in &mut self.data {
*data = u128::max_value();
*data = !0;
}
}
@ -117,53 +162,132 @@ impl<C: Idx> BitArray<C> {
changed
}
pub fn words(&self) -> &[Word] {
&self.data
}
pub fn words_mut(&mut self) -> &mut [Word] {
&mut self.data
}
/// Iterates over indexes of set bits in a sorted order
#[inline]
pub fn iter<'a>(&'a self) -> BitIter<'a, C> {
BitIter {
iter: self.data.iter(),
current: 0,
idx: 0,
cur: None,
iter: self.data.iter().enumerate(),
marker: PhantomData,
}
}
}
impl<T: Idx> rustc_serialize::Encodable for BitArray<T> {
fn encode<E: rustc_serialize::Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.data.encode(encoder)
}
}
impl<T: Idx> rustc_serialize::Decodable for BitArray<T> {
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<BitArray<T>, D::Error> {
let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
Ok(BitArray {
data: words,
marker: PhantomData,
})
}
}
pub struct BitIter<'a, C: Idx> {
iter: ::std::slice::Iter<'a, Word>,
current: Word,
idx: usize,
cur: Option<(Word, usize)>,
iter: iter::Enumerate<slice::Iter<'a, Word>>,
marker: PhantomData<C>
}
impl<'a, C: Idx> Iterator for BitIter<'a, C> {
type Item = C;
fn next(&mut self) -> Option<C> {
while self.current == 0 {
self.current = if let Some(&i) = self.iter.next() {
if i == 0 {
self.idx += WORD_BITS;
continue;
} else {
self.idx = words(self.idx) * WORD_BITS;
i
loop {
if let Some((ref mut word, offset)) = self.cur {
let bit_pos = word.trailing_zeros() as usize;
if bit_pos != WORD_BITS {
let bit = 1 << bit_pos;
*word ^= bit;
return Some(C::new(bit_pos + offset))
}
} else {
return None;
}
let (i, word) = self.iter.next()?;
self.cur = Some((*word, WORD_BITS * i));
}
let offset = self.current.trailing_zeros() as usize;
self.current >>= offset;
self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000
self.idx += offset + 1;
Some(C::new(self.idx - 1))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: Word, pred2: Word) -> Word;
}
#[inline]
pub fn bitwise<Op: BitwiseOperator>(out_vec: &mut [Word], in_vec: &[Word], op: &Op) -> bool
{
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) {
let old_val = *out_elem;
let new_val = op.join(old_val, *in_elem);
*out_elem = new_val;
changed |= old_val != new_val;
}
changed
}
pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}
pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut result = String::new();
let mut sep = '[';
// Note: this is a little endian printout of bytes.
// i tracks how many bits we have printed so far.
let mut i = 0;
for &word in words.iter() {
let mut v = word;
for _ in 0..WORD_BYTES { // for each byte in `v`:
let remain = bits - i;
// If less than a byte remains, then mask just that many bits.
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
assert!(mask <= 0xFF);
let byte = v & mask;
result.push_str(&format!("{}{:02x}", sep, byte));
if remain <= 8 { break; }
v >>= 8;
i += 8;
sep = '-';
}
sep = '|';
}
result.push(']');
result
}
/// A resizable BitVector type.
@ -218,7 +342,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
pub fn new(rows: usize, columns: usize) -> BitMatrix<R, C> {
// For every element, we need one bit for every other
// element. Round up to an even number of words.
let words_per_row = words(columns);
let words_per_row = num_words(columns);
BitMatrix {
columns,
vector: vec![0; rows * words_per_row],
@ -229,7 +353,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
/// The range of bits for a given row.
fn range(&self, row: R) -> (usize, usize) {
let row = row.index();
let words_per_row = words(self.columns);
let words_per_row = num_words(self.columns);
let start = row * words_per_row;
(start, start + words_per_row)
}
@ -307,9 +431,8 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
pub fn iter<'a>(&'a self, row: R) -> BitIter<'a, C> {
let (start, end) = self.range(row);
BitIter {
iter: self.vector[start..end].iter(),
current: 0,
idx: 0,
cur: None,
iter: self.vector[start..end].iter().enumerate(),
marker: PhantomData,
}
}
@ -418,7 +541,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
}
#[inline]
fn words<C: Idx>(elements: C) -> usize {
fn num_words<C: Idx>(elements: C) -> usize {
(elements.index() + WORD_BITS - 1) / WORD_BITS
}
@ -430,6 +553,46 @@ fn word_mask<C: Idx>(index: C) -> (usize, Word) {
(word, mask)
}
#[test]
fn test_clear_above() {
use std::cmp;
for i in 0..256 {
let mut idx_buf: BitArray<usize> = BitArray::new_filled(128);
idx_buf.clear_above(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..cmp::min(i, 128)).collect();
assert_eq!(elems, expected);
}
}
#[test]
fn test_set_up_to() {
for i in 0..128 {
for mut idx_buf in
vec![BitArray::new_empty(128), BitArray::new_filled(128)]
.into_iter()
{
idx_buf.set_up_to(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..i).collect();
assert_eq!(elems, expected);
}
}
}
#[test]
fn test_new_filled() {
for i in 0..128 {
let idx_buf = BitArray::new_filled(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..i).collect();
assert_eq!(elems, expected);
}
}
#[test]
fn bitvec_iter_works() {
let mut bitvec: BitArray<usize> = BitArray::new(100);

View file

@ -10,12 +10,9 @@
use array_vec::ArrayVec;
use std::fmt;
use std::iter;
use std::marker::PhantomData;
use std::mem;
use std::slice;
use bitslice::{BitSlice, Word};
use bitslice::{bitwise, Union, Subtract, Intersect};
use bitvec::{bitwise, BitArray, BitIter, Intersect, Subtract, Union, Word, WORD_BITS};
use indexed_vec::Idx;
use rustc_serialize;
@ -40,39 +37,21 @@ pub trait SubtractFromIdxSet<T: Idx> {
/// this type uses to represent the set of object it holds.
///
/// The representation is dense, using one bit per possible element.
#[derive(Eq, PartialEq)]
pub struct IdxSet<T: Idx> {
_pd: PhantomData<fn(&T)>,
bits: Vec<Word>,
}
impl<T: Idx> Clone for IdxSet<T> {
fn clone(&self) -> Self {
IdxSet { _pd: PhantomData, bits: self.bits.clone() }
}
}
#[derive(Clone, Eq, PartialEq)]
pub struct IdxSet<T: Idx>(BitArray<T>);
impl<T: Idx> rustc_serialize::Encodable for IdxSet<T> {
fn encode<E: rustc_serialize::Encoder>(&self,
encoder: &mut E)
-> Result<(), E::Error> {
self.bits.encode(encoder)
fn encode<E: rustc_serialize::Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.0.encode(encoder)
}
}
impl<T: Idx> rustc_serialize::Decodable for IdxSet<T> {
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<IdxSet<T>, D::Error> {
let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
Ok(IdxSet {
_pd: PhantomData,
bits: words,
})
Ok(IdxSet(rustc_serialize::Decodable::decode(d)?))
}
}
const BITS_PER_WORD: usize = mem::size_of::<Word>() * 8;
impl<T: Idx> fmt::Debug for IdxSet<T> {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
w.debug_list()
@ -82,31 +61,21 @@ impl<T: Idx> fmt::Debug for IdxSet<T> {
}
impl<T: Idx> IdxSet<T> {
fn new(init: Word, domain_size: usize) -> Self {
let num_words = (domain_size + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
IdxSet {
_pd: Default::default(),
bits: vec![init; num_words],
}
/// Creates set holding no elements.
pub fn new_empty(domain_size: usize) -> Self {
IdxSet(BitArray::new_empty(domain_size))
}
/// Creates set holding every element whose index falls in range 0..domain_size.
pub fn new_filled(domain_size: usize) -> Self {
let mut result = Self::new(!0, domain_size);
result.trim_to(domain_size);
result
}
/// Creates set holding no elements.
pub fn new_empty(domain_size: usize) -> Self {
Self::new(0, domain_size)
IdxSet(BitArray::new_filled(domain_size))
}
/// Duplicates as a hybrid set.
pub fn to_hybrid(&self) -> HybridIdxSet<T> {
// This domain_size may be slightly larger than the one specified
// upon creation, due to rounding up to a whole word. That's ok.
let domain_size = self.bits.len() * BITS_PER_WORD;
let domain_size = self.words().len() * WORD_BITS;
// Note: we currently don't bother trying to make a Sparse set.
HybridIdxSet::Dense(self.to_owned(), domain_size)
@ -114,60 +83,35 @@ impl<T: Idx> IdxSet<T> {
/// Removes all elements
pub fn clear(&mut self) {
for b in &mut self.bits {
*b = 0;
}
self.0.clear();
}
/// Sets all elements up to `domain_size`
pub fn set_up_to(&mut self, domain_size: usize) {
for b in &mut self.bits {
*b = !0;
}
self.trim_to(domain_size);
}
/// Clear all elements above `domain_size`.
fn trim_to(&mut self, domain_size: usize) {
// `trim_block` is the first block where some bits have
// to be cleared.
let trim_block = domain_size / BITS_PER_WORD;
// all the blocks above it have to be completely cleared.
if trim_block < self.bits.len() {
for b in &mut self.bits[trim_block+1..] {
*b = 0;
}
// at that block, the `domain_size % BITS_PER_WORD` LSBs
// should remain.
let remaining_bits = domain_size % BITS_PER_WORD;
let mask = (1<<remaining_bits)-1;
self.bits[trim_block] &= mask;
}
self.0.set_up_to(domain_size);
}
/// Removes `elem` from the set `self`; returns true iff this changed `self`.
pub fn remove(&mut self, elem: &T) -> bool {
self.bits.clear_bit(elem.index())
self.0.remove(*elem)
}
/// Adds `elem` to the set `self`; returns true iff this changed `self`.
pub fn add(&mut self, elem: &T) -> bool {
self.bits.set_bit(elem.index())
self.0.insert(*elem)
}
/// Returns true iff set `self` contains `elem`.
pub fn contains(&self, elem: &T) -> bool {
self.bits.get_bit(elem.index())
self.0.contains(*elem)
}
pub fn words(&self) -> &[Word] {
&self.bits
self.0.words()
}
pub fn words_mut(&mut self) -> &mut [Word] {
&mut self.bits
self.0.words_mut()
}
/// Efficiently overwrite `self` with `other`. Panics if `self` and `other`
@ -196,9 +140,7 @@ impl<T: Idx> IdxSet<T> {
pub fn iter(&self) -> Iter<T> {
Iter {
cur: None,
iter: self.words().iter().enumerate(),
_pd: PhantomData,
iter: self.0.iter()
}
}
}
@ -216,28 +158,14 @@ impl<T: Idx> SubtractFromIdxSet<T> for IdxSet<T> {
}
pub struct Iter<'a, T: Idx> {
cur: Option<(Word, usize)>,
iter: iter::Enumerate<slice::Iter<'a, Word>>,
_pd: PhantomData<fn(&T)>,
iter: BitIter<'a, T>
}
impl<'a, T: Idx> Iterator for Iter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
loop {
if let Some((ref mut word, offset)) = self.cur {
let bit_pos = word.trailing_zeros() as usize;
if bit_pos != BITS_PER_WORD {
let bit = 1 << bit_pos;
*word ^= bit;
return Some(T::new(bit_pos + offset))
}
}
let (i, word) = self.iter.next()?;
self.cur = Some((*word, BITS_PER_WORD * i));
}
self.iter.next()
}
}
@ -456,43 +384,3 @@ impl<'a, T: Idx> Iterator for HybridIter<'a, T> {
}
}
}
#[test]
fn test_trim_to() {
use std::cmp;
for i in 0..256 {
let mut idx_buf: IdxSet<usize> = IdxSet::new_filled(128);
idx_buf.trim_to(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..cmp::min(i, 128)).collect();
assert_eq!(elems, expected);
}
}
#[test]
fn test_set_up_to() {
for i in 0..128 {
for mut idx_buf in
vec![IdxSet::new_empty(128), IdxSet::new_filled(128)]
.into_iter()
{
idx_buf.set_up_to(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..i).collect();
assert_eq!(elems, expected);
}
}
}
#[test]
fn test_new_filled() {
for i in 0..128 {
let idx_buf = IdxSet::new_filled(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..i).collect();
assert_eq!(elems, expected);
}
}

View file

@ -63,7 +63,6 @@ pub use rustc_serialize::hex::ToHex;
pub mod svh;
pub mod array_vec;
pub mod base_n;
pub mod bitslice;
pub mod bitvec;
pub mod const_cstr;
pub mod flock;

View file

@ -12,7 +12,7 @@
use syntax::ast::NodeId;
use rustc::mir::{BasicBlock, Mir};
use rustc_data_structures::bitslice::bits_to_string;
use rustc_data_structures::bitvec::bits_to_string;
use dot;
use dot::IntoCow;

View file

@ -20,7 +20,7 @@ use rustc::ty::TyCtxt;
use rustc::ty::{RegionKind, RegionVid};
use rustc::ty::RegionKind::ReScope;
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::bitvec::{BitwiseOperator, Word};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_set::IdxSet;
use rustc_data_structures::indexed_vec::IndexVec;

View file

@ -14,7 +14,7 @@
use rustc::ty::TyCtxt;
use rustc::mir::{self, Mir, Location};
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::bitvec::{BitwiseOperator, Word};
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::Idx;

View file

@ -10,7 +10,7 @@
use syntax::ast::{self, MetaItem};
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
use rustc_data_structures::bitvec::{bitwise, BitwiseOperator};
use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::work_queue::WorkQueue;