Skip to content

Commit 149307e

Browse files
Improve BitSet APIs
A few small cleanups to `BitSet` and friends: - Overload `clone_from` for `BitSet`. - Improve `Debug` represenation of `HybridBitSet`. - Make `HybridBitSet::domain_size` public. - Don't require `T: Idx` at the type level. The `Idx` bound is still on most `BitSet` methods, but like `HashMap`, it doesn't need to be satisfied for the type to exist.
1 parent 85fbf49 commit 149307e

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

compiler/rustc_index/src/bit_set.rs

+37-17
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,20 @@ pub const WORD_BITS: usize = WORD_BYTES * 8;
2828
/// will panic if the bitsets have differing domain sizes.
2929
///
3030
/// [`GrowableBitSet`]: struct.GrowableBitSet.html
31-
#[derive(Clone, Eq, PartialEq, Decodable, Encodable)]
32-
pub struct BitSet<T: Idx> {
31+
#[derive(Eq, PartialEq, Decodable, Encodable)]
32+
pub struct BitSet<T> {
3333
domain_size: usize,
3434
words: Vec<Word>,
3535
marker: PhantomData<T>,
3636
}
3737

38+
impl<T> BitSet<T> {
39+
/// Gets the domain size.
40+
pub fn domain_size(&self) -> usize {
41+
self.domain_size
42+
}
43+
}
44+
3845
impl<T: Idx> BitSet<T> {
3946
/// Creates a new, empty bitset with a given `domain_size`.
4047
#[inline]
@@ -52,11 +59,6 @@ impl<T: Idx> BitSet<T> {
5259
result
5360
}
5461

55-
/// Gets the domain size.
56-
pub fn domain_size(&self) -> usize {
57-
self.domain_size
58-
}
59-
6062
/// Clear all elements.
6163
#[inline]
6264
pub fn clear(&mut self) {
@@ -75,12 +77,6 @@ impl<T: Idx> BitSet<T> {
7577
}
7678
}
7779

78-
/// Efficiently overwrite `self` with `other`.
79-
pub fn overwrite(&mut self, other: &BitSet<T>) {
80-
assert!(self.domain_size == other.domain_size);
81-
self.words.clone_from_slice(&other.words);
82-
}
83-
8480
/// Count the number of set bits in the set.
8581
pub fn count(&self) -> usize {
8682
self.words.iter().map(|e| e.count_ones() as usize).sum()
@@ -243,6 +239,21 @@ impl<T: Idx> SubtractFromBitSet<T> for BitSet<T> {
243239
}
244240
}
245241

242+
impl<T> Clone for BitSet<T> {
243+
fn clone(&self) -> Self {
244+
BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
245+
}
246+
247+
fn clone_from(&mut self, from: &Self) {
248+
if self.domain_size != from.domain_size {
249+
self.words.resize(from.domain_size, 0);
250+
self.domain_size = from.domain_size;
251+
}
252+
253+
self.words.copy_from_slice(&from.words);
254+
}
255+
}
256+
246257
impl<T: Idx> fmt::Debug for BitSet<T> {
247258
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
248259
w.debug_list().entries(self.iter()).finish()
@@ -363,7 +374,7 @@ const SPARSE_MAX: usize = 8;
363374
///
364375
/// This type is used by `HybridBitSet`; do not use directly.
365376
#[derive(Clone, Debug)]
366-
pub struct SparseBitSet<T: Idx> {
377+
pub struct SparseBitSet<T> {
367378
domain_size: usize,
368379
elems: ArrayVec<[T; SPARSE_MAX]>,
369380
}
@@ -464,18 +475,27 @@ impl<T: Idx> SubtractFromBitSet<T> for SparseBitSet<T> {
464475
/// All operations that involve an element will panic if the element is equal
465476
/// to or greater than the domain size. All operations that involve two bitsets
466477
/// will panic if the bitsets have differing domain sizes.
467-
#[derive(Clone, Debug)]
468-
pub enum HybridBitSet<T: Idx> {
478+
#[derive(Clone)]
479+
pub enum HybridBitSet<T> {
469480
Sparse(SparseBitSet<T>),
470481
Dense(BitSet<T>),
471482
}
472483

484+
impl<T: Idx> fmt::Debug for HybridBitSet<T> {
485+
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
486+
match self {
487+
Self::Sparse(b) => b.fmt(w),
488+
Self::Dense(b) => b.fmt(w),
489+
}
490+
}
491+
}
492+
473493
impl<T: Idx> HybridBitSet<T> {
474494
pub fn new_empty(domain_size: usize) -> Self {
475495
HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
476496
}
477497

478-
fn domain_size(&self) -> usize {
498+
pub fn domain_size(&self) -> usize {
479499
match self {
480500
HybridBitSet::Sparse(sparse) => sparse.domain_size,
481501
HybridBitSet::Dense(dense) => dense.domain_size,

0 commit comments

Comments
 (0)