diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs deleted file mode 100644 index 45fb5657061..00000000000 --- a/src/librustc_data_structures/array_vec.rs +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A stack-allocated vector, allowing storage of N elements on the stack. - -use std::marker::Unsize; -use std::iter::Extend; -use std::ptr::{self, drop_in_place, NonNull}; -use std::ops::{Deref, DerefMut, Range}; -use std::hash::{Hash, Hasher}; -use std::slice; -use std::fmt; -use std::mem; -use std::mem::ManuallyDrop; -use std::ops::Bound::{Excluded, Included, Unbounded}; -use std::ops::RangeBounds; - -pub unsafe trait Array { - type Element; - type PartialStorage: Unsize<[ManuallyDrop]>; - const LEN: usize; -} - -unsafe impl Array for [T; 1] { - type Element = T; - type PartialStorage = [ManuallyDrop; 1]; - const LEN: usize = 1; -} - -unsafe impl Array for [T; 8] { - type Element = T; - type PartialStorage = [ManuallyDrop; 8]; - const LEN: usize = 8; -} - -unsafe impl Array for [T; 32] { - type Element = T; - type PartialStorage = [ManuallyDrop; 32]; - const LEN: usize = 32; -} - -pub struct ArrayVec { - count: usize, - values: A::PartialStorage -} - -impl Hash for ArrayVec - where A: Array, - A::Element: Hash { - fn hash(&self, state: &mut H) where H: Hasher { - (&self[..]).hash(state); - } -} - -impl Clone for ArrayVec - where A: Array, - A::Element: Clone { - fn clone(&self) -> Self { - let mut v = ArrayVec::new(); - v.extend(self.iter().cloned()); - v - } -} - -impl ArrayVec { - pub fn new() -> Self { - ArrayVec { - count: 0, - values: unsafe { ::std::mem::uninitialized() }, - } - } - - pub fn len(&self) -> usize { - self.count - } - - pub unsafe fn set_len(&mut self, len: usize) { - self.count = len; - } - - /// Panics when the stack vector is full. - pub fn push(&mut self, el: A::Element) { - let arr = &mut self.values as &mut [ManuallyDrop<_>]; - arr[self.count] = ManuallyDrop::new(el); - self.count += 1; - } - - pub fn pop(&mut self) -> Option { - if self.count > 0 { - let arr = &mut self.values as &mut [ManuallyDrop<_>]; - self.count -= 1; - unsafe { - let value = ptr::read(&*arr[self.count]); - Some(value) - } - } else { - None - } - } - - pub fn drain(&mut self, range: R) -> Drain - where R: RangeBounds - { - // Memory safety - // - // When the Drain is first created, it shortens the length of - // the source vector to make sure no uninitialized or moved-from elements - // are accessible at all if the Drain's destructor never gets to run. - // - // Drain will ptr::read out the values to remove. - // When finished, remaining tail of the vec is copied back to cover - // the hole, and the vector length is restored to the new length. - // - let len = self.len(); - let start = match range.start_bound() { - Included(&n) => n, - Excluded(&n) => n + 1, - Unbounded => 0, - }; - let end = match range.end_bound() { - Included(&n) => n + 1, - Excluded(&n) => n, - Unbounded => len, - }; - assert!(start <= end); - assert!(end <= len); - - unsafe { - // set self.vec length's to start, to be safe in case Drain is leaked - self.set_len(start); - // Use the borrow in the IterMut to indicate borrowing behavior of the - // whole Drain iterator (like &mut T). - let range_slice = { - let arr = &mut self.values as &mut [ManuallyDrop<::Element>]; - slice::from_raw_parts_mut(arr.as_mut_ptr().add(start), - end - start) - }; - Drain { - tail_start: end, - tail_len: len - end, - iter: range_slice.iter(), - array_vec: NonNull::from(self), - } - } - } -} - -impl Default for ArrayVec - where A: Array { - fn default() -> Self { - ArrayVec::new() - } -} - -impl fmt::Debug for ArrayVec - where A: Array, - A::Element: fmt::Debug { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self[..].fmt(f) - } -} - -impl Deref for ArrayVec { - type Target = [A::Element]; - fn deref(&self) -> &Self::Target { - unsafe { - slice::from_raw_parts(&self.values as *const _ as *const A::Element, self.count) - } - } -} - -impl DerefMut for ArrayVec { - fn deref_mut(&mut self) -> &mut [A::Element] { - unsafe { - slice::from_raw_parts_mut(&mut self.values as *mut _ as *mut A::Element, self.count) - } - } -} - -impl Drop for ArrayVec { - fn drop(&mut self) { - unsafe { - drop_in_place(&mut self[..]) - } - } -} - -impl Extend for ArrayVec { - fn extend(&mut self, iter: I) where I: IntoIterator { - for el in iter { - self.push(el); - } - } -} - -pub struct Iter { - indices: Range, - store: A::PartialStorage, -} - -impl Drop for Iter { - fn drop(&mut self) { - self.for_each(drop); - } -} - -impl Iterator for Iter { - type Item = A::Element; - - fn next(&mut self) -> Option { - let arr = &self.store as &[ManuallyDrop<_>]; - unsafe { - self.indices.next().map(|i| ptr::read(&*arr[i])) - } - } - - fn size_hint(&self) -> (usize, Option) { - self.indices.size_hint() - } -} - -pub struct Drain<'a, A: Array> - where A::Element: 'a -{ - tail_start: usize, - tail_len: usize, - iter: slice::Iter<'a, ManuallyDrop>, - array_vec: NonNull>, -} - -impl<'a, A: Array> Iterator for Drain<'a, A> { - type Item = A::Element; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().map(|elt| unsafe { ptr::read(&**elt) }) - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl<'a, A: Array> Drop for Drain<'a, A> { - fn drop(&mut self) { - // exhaust self first - self.for_each(drop); - - if self.tail_len > 0 { - unsafe { - let source_array_vec: &mut ArrayVec = self.array_vec.as_mut(); - // memmove back untouched tail, update to new length - let start = source_array_vec.len(); - let tail = self.tail_start; - { - let arr = - &mut source_array_vec.values as &mut [ManuallyDrop<::Element>]; - let src = arr.as_ptr().add(tail); - let dst = arr.as_mut_ptr().add(start); - ptr::copy(src, dst, self.tail_len); - }; - source_array_vec.set_len(start + self.tail_len); - } - } - } -} - -impl IntoIterator for ArrayVec { - type Item = A::Element; - type IntoIter = Iter; - fn into_iter(self) -> Self::IntoIter { - let store = unsafe { - ptr::read(&self.values) - }; - let indices = 0..self.count; - mem::forget(self); - Iter { - indices, - store, - } - } -} - -impl<'a, A: Array> IntoIterator for &'a ArrayVec { - type Item = &'a A::Element; - type IntoIter = slice::Iter<'a, A::Element>; - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a, A: Array> IntoIterator for &'a mut ArrayVec { - type Item = &'a mut A::Element; - type IntoIter = slice::IterMut<'a, A::Element>; - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() - } -} diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index b1fb475bce9..9eb8d0afd46 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use array_vec::ArrayVec; use indexed_vec::{Idx, IndexVec}; use rustc_serialize; +use smallvec::SmallVec; use std::fmt; use std::iter; use std::marker::PhantomData; @@ -61,21 +61,21 @@ impl BitSet { } /// Sets all elements up to and including `size`. - pub fn set_up_to(&mut self, bit: usize) { + pub fn set_up_to(&mut self, elem: usize) { for word in &mut self.words { *word = !0; } - self.clear_above(bit); + self.clear_above(elem); } - /// Clear all elements above `bit`. - fn clear_above(&mut self, bit: usize) { - let first_clear_block = bit / WORD_BITS; + /// Clear all elements above `elem`. + fn clear_above(&mut self, elem: usize) { + let first_clear_block = elem / WORD_BITS; if first_clear_block < self.words.len() { - // Within `first_clear_block`, the `bit % WORD_BITS` LSBs should + // Within `first_clear_block`, the `elem % WORD_BITS` LSBs should // remain. - let mask = (1 << (bit % WORD_BITS)) - 1; + let mask = (1 << (elem % WORD_BITS)) - 1; self.words[first_clear_block] &= mask; // All the blocks above `first_clear_block` are fully cleared. @@ -96,10 +96,10 @@ impl BitSet { self.words.iter().map(|e| e.count_ones() as usize).sum() } - /// True if `self` contains the bit `bit`. + /// True if `self` contains `elem`. #[inline] - pub fn contains(&self, bit: T) -> bool { - let (word_index, mask) = word_index_and_mask(bit); + pub fn contains(&self, elem: T) -> bool { + let (word_index, mask) = word_index_and_mask(elem); (self.words[word_index] & mask) != 0 } @@ -118,10 +118,10 @@ impl BitSet { self.words.iter().all(|a| *a == 0) } - /// Insert a bit. Returns true if the bit has changed. + /// Insert `elem`. Returns true if the set has changed. #[inline] - pub fn insert(&mut self, bit: T) -> bool { - let (word_index, mask) = word_index_and_mask(bit); + pub fn insert(&mut self, elem: T) -> bool { + let (word_index, mask) = word_index_and_mask(elem); let word_ref = &mut self.words[word_index]; let word = *word_ref; let new_word = word | mask; @@ -136,10 +136,10 @@ impl BitSet { } } - /// Returns true if the bit has changed. + /// Returns true if the set has changed. #[inline] - pub fn remove(&mut self, bit: T) -> bool { - let (word_index, mask) = word_index_and_mask(bit); + pub fn remove(&mut self, elem: T) -> bool { + let (word_index, mask) = word_index_and_mask(elem); let word_ref = &mut self.words[word_index]; let word = *word_ref; let new_word = word & !mask; @@ -320,31 +320,44 @@ fn bitwise(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool const SPARSE_MAX: usize = 8; /// A fixed-size bitset type with a sparse representation and a maximum of -/// SPARSE_MAX elements. The elements are stored as an unsorted vector with no -/// duplicates. +/// `SPARSE_MAX` elements. The elements are stored as a sorted `SmallVec` with +/// no duplicates; although `SmallVec` can spill its elements to the heap, that +/// never happens within this type because of the `SPARSE_MAX` limit. /// -/// This type is used by HybridBitSet; do not use directly. +/// This type is used by `HybridBitSet`; do not use directly. #[derive(Clone, Debug)] -pub struct SparseBitSet(ArrayVec<[T; SPARSE_MAX]>); +pub struct SparseBitSet(SmallVec<[T; SPARSE_MAX]>); impl SparseBitSet { fn new_empty() -> Self { - SparseBitSet(ArrayVec::new()) + SparseBitSet(SmallVec::new()) } fn len(&self) -> usize { self.0.len() } + fn is_empty(&self) -> bool { + self.0.len() == 0 + } + fn contains(&self, elem: T) -> bool { self.0.contains(&elem) } fn insert(&mut self, elem: T) -> bool { - // Ensure there are no duplicates. - if self.0.contains(&elem) { - false + assert!(self.len() < SPARSE_MAX); + if let Some(i) = self.0.iter().position(|&e| e >= elem) { + if self.0[i] == elem { + // `elem` is already in the set. + false + } else { + // `elem` is smaller than one or more existing elements. + self.0.insert(i, elem); + true + } } else { + // `elem` is larger than all existing elements. self.0.push(elem); true } @@ -352,10 +365,7 @@ impl SparseBitSet { fn remove(&mut self, elem: T) -> bool { if let Some(i) = self.0.iter().position(|&e| e == elem) { - // Swap the found element to the end, then pop it. - let len = self.0.len(); - self.0.swap(i, len - 1); - self.0.pop(); + self.0.remove(i); true } else { false @@ -396,8 +406,8 @@ impl SubtractFromBitSet for SparseBitSet { } /// A fixed-size bitset type with a hybrid representation: sparse when there -/// are up to a SPARSE_MAX elements in the set, but dense when there are more -/// than SPARSE_MAX. +/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more +/// than `SPARSE_MAX`. /// /// This type is especially efficient for sets that typically have a small /// number of elements, but a large `domain_size`, and are cleared frequently. @@ -411,15 +421,28 @@ pub enum HybridBitSet { } impl HybridBitSet { + // FIXME: This function is used in conjunction with `mem::replace()` in + // several pieces of awful code below. I can't work out how else to appease + // the borrow checker. + fn dummy() -> Self { + // The cheapest HybridBitSet to construct, which is only used to get + // around the borrow checker. + HybridBitSet::Sparse(SparseBitSet::new_empty(), 0) + } + pub fn new_empty(domain_size: usize) -> Self { HybridBitSet::Sparse(SparseBitSet::new_empty(), domain_size) } - pub fn clear(&mut self) { - let domain_size = match *self { + pub fn domain_size(&self) -> usize { + match *self { HybridBitSet::Sparse(_, size) => size, HybridBitSet::Dense(_, size) => size, - }; + } + } + + pub fn clear(&mut self) { + let domain_size = self.domain_size(); *self = HybridBitSet::new_empty(domain_size); } @@ -430,6 +453,22 @@ impl HybridBitSet { } } + pub fn superset(&self, other: &HybridBitSet) -> bool { + match (self, other) { + (HybridBitSet::Dense(self_dense, _), HybridBitSet::Dense(other_dense, _)) => { + self_dense.superset(other_dense) + } + _ => other.iter().all(|elem| self.contains(elem)), + } + } + + pub fn is_empty(&self) -> bool { + match self { + HybridBitSet::Sparse(sparse, _) => sparse.is_empty(), + HybridBitSet::Dense(dense, _) => dense.is_empty(), + } + } + pub fn insert(&mut self, elem: T) -> bool { match self { HybridBitSet::Sparse(sparse, _) if sparse.len() < SPARSE_MAX => { @@ -443,19 +482,15 @@ impl HybridBitSet { } HybridBitSet::Sparse(_, _) => { // The set is sparse and full. Convert to a dense set. - // - // FIXME: This code is awful, but I can't work out how else to - // appease the borrow checker. - let dummy = HybridBitSet::Sparse(SparseBitSet::new_empty(), 0); - match mem::replace(self, dummy) { + match mem::replace(self, HybridBitSet::dummy()) { HybridBitSet::Sparse(sparse, domain_size) => { let mut dense = sparse.to_dense(domain_size); let changed = dense.insert(elem); assert!(changed); - mem::replace(self, HybridBitSet::Dense(dense, domain_size)); + *self = HybridBitSet::Dense(dense, domain_size); changed } - _ => panic!("impossible"), + _ => unreachable!() } } @@ -463,6 +498,17 @@ impl HybridBitSet { } } + pub fn insert_all(&mut self) { + let domain_size = self.domain_size(); + match self { + HybridBitSet::Sparse(_, _) => { + let dense = BitSet::new_filled(domain_size); + *self = HybridBitSet::Dense(dense, domain_size); + } + HybridBitSet::Dense(dense, _) => dense.insert_all(), + } + } + pub fn remove(&mut self, elem: T) -> bool { // Note: we currently don't bother going from Dense back to Sparse. match self { @@ -471,6 +517,42 @@ impl HybridBitSet { } } + pub fn union(&mut self, other: &HybridBitSet) -> bool { + match self { + HybridBitSet::Sparse(_, _) => { + match other { + HybridBitSet::Sparse(other_sparse, _) => { + // Both sets are sparse. Add the elements in + // `other_sparse` to `self_hybrid` one at a time. This + // may or may not cause `self_hybrid` to be densified. + let mut self_hybrid = mem::replace(self, HybridBitSet::dummy()); + let mut changed = false; + for elem in other_sparse.iter() { + changed |= self_hybrid.insert(*elem); + } + *self = self_hybrid; + changed + } + HybridBitSet::Dense(other_dense, _) => { + // `self` is sparse and `other` is dense. Densify + // `self` and then do the bitwise union. + match mem::replace(self, HybridBitSet::dummy()) { + HybridBitSet::Sparse(self_sparse, self_domain_size) => { + let mut new_dense = self_sparse.to_dense(self_domain_size); + let changed = new_dense.union(other_dense); + *self = HybridBitSet::Dense(new_dense, self_domain_size); + changed + } + _ => unreachable!() + } + } + } + } + + HybridBitSet::Dense(self_dense, _) => self_dense.union(other), + } + } + /// Converts to a dense set, consuming itself in the process. pub fn to_dense(self) -> BitSet { match self { @@ -479,7 +561,6 @@ impl HybridBitSet { } } - /// Iteration order is unspecified. pub fn iter(&self) -> HybridIter { match self { HybridBitSet::Sparse(sparse, _) => HybridIter::Sparse(sparse.iter()), @@ -547,16 +628,16 @@ impl GrowableBitSet { GrowableBitSet { bit_set: BitSet::new_empty(bits) } } - /// Returns true if the bit has changed. + /// Returns true if the set has changed. #[inline] - pub fn insert(&mut self, bit: T) -> bool { - self.grow(bit); - self.bit_set.insert(bit) + pub fn insert(&mut self, elem: T) -> bool { + self.grow(elem); + self.bit_set.insert(elem) } #[inline] - pub fn contains(&self, bit: T) -> bool { - let (word_index, mask) = word_index_and_mask(bit); + pub fn contains(&self, elem: T) -> bool { + let (word_index, mask) = word_index_and_mask(elem); if let Some(word) = self.bit_set.words.get(word_index) { (word & mask) != 0 } else { @@ -682,11 +763,10 @@ impl BitMatrix { /// sparse representation. /// /// Initially, every row has no explicit representation. If any bit within a -/// row is set, the entire row is instantiated as -/// `Some()`. Furthermore, any previously -/// uninstantiated rows prior to it will be instantiated as `None`. Those prior -/// rows may themselves become fully instantiated later on if any of their bits -/// are set. +/// row is set, the entire row is instantiated as `Some()`. +/// Furthermore, any previously uninstantiated rows prior to it will be +/// instantiated as `None`. Those prior rows may themselves become fully +/// instantiated later on if any of their bits are set. /// /// `R` and `C` are index types used to identify rows and columns respectively; /// typically newtyped `usize` wrappers, but they can also just be `usize`. @@ -697,7 +777,7 @@ where C: Idx, { num_columns: usize, - rows: IndexVec>>, + rows: IndexVec>>, } impl SparseBitMatrix { @@ -709,14 +789,14 @@ impl SparseBitMatrix { } } - fn ensure_row(&mut self, row: R) -> &mut BitSet { + fn ensure_row(&mut self, row: R) -> &mut HybridBitSet { // Instantiate any missing rows up to and including row `row` with an - // empty BitSet. + // empty HybridBitSet. self.rows.ensure_contains_elem(row, || None); - // Then replace row `row` with a full BitSet if necessary. + // Then replace row `row` with a full HybridBitSet if necessary. let num_columns = self.num_columns; - self.rows[row].get_or_insert_with(|| BitSet::new_empty(num_columns)) + self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns)) } /// Sets the cell at `(row, column)` to true. Put another way, insert @@ -755,8 +835,8 @@ impl SparseBitMatrix { } } - /// Merge a row, `from`, into the `into` row. - pub fn union_into_row(&mut self, into: R, from: &BitSet) -> bool { + /// Union a row, `from`, into the `into` row. + pub fn union_into_row(&mut self, into: R, from: &HybridBitSet) -> bool { self.ensure_row(into).union(from) } @@ -775,7 +855,7 @@ impl SparseBitMatrix { self.row(row).into_iter().flat_map(|r| r.iter()) } - pub fn row(&self, row: R) -> Option<&BitSet> { + pub fn row(&self, row: R) -> Option<&HybridBitSet> { if let Some(Some(row)) = self.rows.get(row) { Some(row) } else { @@ -866,7 +946,7 @@ fn bitset_iter_works_2() { } #[test] -fn union_two_vecs() { +fn union_two_sets() { let mut set1: BitSet = BitSet::new_empty(65); let mut set2: BitSet = BitSet::new_empty(65); assert!(set1.insert(3)); @@ -882,6 +962,74 @@ fn union_two_vecs() { assert!(set1.contains(64)); } +#[test] +fn hybrid_bitset() { + let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); + assert!(sparse038.is_empty()); + assert!(sparse038.insert(0)); + assert!(sparse038.insert(1)); + assert!(sparse038.insert(8)); + assert!(sparse038.insert(3)); + assert!(!sparse038.insert(3)); + assert!(sparse038.remove(1)); + assert!(!sparse038.is_empty()); + assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); + + for i in 0..256 { + if i == 0 || i == 3 || i == 8 { + assert!(sparse038.contains(i)); + } else { + assert!(!sparse038.contains(i)); + } + } + + let mut sparse01358 = sparse038.clone(); + assert!(sparse01358.insert(1)); + assert!(sparse01358.insert(5)); + assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); + + let mut dense10 = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(dense10.insert(i)); + } + assert!(!dense10.is_empty()); + assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + + let mut dense256 = HybridBitSet::new_empty(256); + assert!(dense256.is_empty()); + dense256.insert_all(); + assert!(!dense256.is_empty()); + for i in 0..256 { + assert!(dense256.contains(i)); + } + + assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) + assert!(sparse01358.superset(&sparse038)); // sparse + sparse + assert!(dense10.superset(&sparse038)); // dense + sparse + assert!(dense10.superset(&dense10)); // dense + dense (self) + assert!(dense256.superset(&dense10)); // dense + dense + + let mut hybrid = sparse038; + assert!(!sparse01358.union(&hybrid)); // no change + assert!(hybrid.union(&sparse01358)); + assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); + assert!(!dense10.union(&sparse01358)); + assert!(!dense256.union(&dense10)); + let mut dense = dense10; + assert!(dense.union(&dense256)); + assert!(dense.superset(&dense256) && dense256.superset(&dense)); + assert!(hybrid.union(&dense256)); + assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); + + assert_eq!(dense256.iter().count(), 256); + let mut dense0 = dense256; + for i in 0..256 { + assert!(dense0.remove(i)); + } + assert!(!dense0.remove(0)); + assert!(dense0.is_empty()); +} + #[test] fn grow() { let mut set: GrowableBitSet = GrowableBitSet::with_capacity(65); diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 1d7557953e9..70b960ac351 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -60,7 +60,6 @@ extern crate rustc_cratesio_shim; pub use rustc_serialize::hex::ToHex; pub mod svh; -pub mod array_vec; pub mod base_n; pub mod bit_set; pub mod const_cstr; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 618bf99c7c0..8dc41a9b2d3 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -10,7 +10,7 @@ use rustc::mir::{BasicBlock, Location, Mir}; use rustc::ty::{self, RegionVid}; -use rustc_data_structures::bit_set::{BitSet, SparseBitMatrix}; +use rustc_data_structures::bit_set::{HybridBitSet, SparseBitMatrix}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::IndexVec; use std::fmt::Debug; @@ -184,7 +184,7 @@ impl LivenessValues { /// Adds all the elements in the given bit array into the given /// region. Returns true if any of them are newly added. - crate fn add_elements(&mut self, row: N, locations: &BitSet) -> bool { + crate fn add_elements(&mut self, row: N, locations: &HybridBitSet) -> bool { debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations); self.points.union_into_row(row, locations) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index b6410f7de3d..47e6ce05cec 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -22,7 +22,7 @@ use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; use rustc::ty::{Ty, TypeFoldable}; -use rustc_data_structures::bit_set::BitSet; +use rustc_data_structures::bit_set::HybridBitSet; use rustc_data_structures::fx::FxHashMap; use std::rc::Rc; use util::liveness::LiveVariableMap; @@ -121,16 +121,16 @@ where cx: LivenessContext<'me, 'typeck, 'flow, 'gcx, 'tcx>, /// Set of points that define the current local. - defs: BitSet, + defs: HybridBitSet, /// Points where the current variable is "use live" -- meaning /// that there is a future "full use" that may use its value. - use_live_at: BitSet, + use_live_at: HybridBitSet, /// Points where the current variable is "drop live" -- meaning /// that there is no future "full use" that may use its value, but /// there is a future drop. - drop_live_at: BitSet, + drop_live_at: HybridBitSet, /// Locations where drops may occur. drop_locations: Vec, @@ -144,9 +144,9 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> { let num_points = cx.elements.num_points(); LivenessResults { cx, - defs: BitSet::new_empty(num_points), - use_live_at: BitSet::new_empty(num_points), - drop_live_at: BitSet::new_empty(num_points), + defs: HybridBitSet::new_empty(num_points), + use_live_at: HybridBitSet::new_empty(num_points), + drop_live_at: HybridBitSet::new_empty(num_points), drop_locations: vec![], stack: vec![], } @@ -448,7 +448,7 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> { fn add_use_live_facts_for( &mut self, value: impl TypeFoldable<'tcx>, - live_at: &BitSet, + live_at: &HybridBitSet, ) { debug!("add_use_live_facts_for(value={:?})", value); @@ -465,7 +465,7 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> { dropped_local: Local, dropped_ty: Ty<'tcx>, drop_locations: &[Location], - live_at: &BitSet, + live_at: &HybridBitSet, ) { debug!( "add_drop_live_constraint(\ @@ -508,7 +508,7 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> { elements: &RegionValueElements, typeck: &mut TypeChecker<'_, '_, 'tcx>, value: impl TypeFoldable<'tcx>, - live_at: &BitSet, + live_at: &HybridBitSet, ) { debug!("make_all_regions_live(value={:?})", value); debug!(