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`.
resolve: Future proof derive helper attributes
Derive helpers no longer require going through recovery mode (fixes https://github.com/rust-lang/rust/issues/53481).
They also report an error if they are ambiguous with any other macro in scope, so we can resolve the question about their exact priority sometime later (cc https://github.com/rust-lang/rust/issues/52226).
Previously the code below would not be guaranteed to exit when the first
spawned thread took the `return, // already unparked` path because there
was no write to synchronize with a read in `park`.
```
use std::sync::atomic::{AtomicBool, Ordering};
use std:🧵:{current, spawn, park};
static FLAG: AtomicBool = AtomicBool::new(false);
fn main() {
let thread_0 = current();
spawn(move || {
FLAG.store(true, Ordering::Relaxed);
thread_0.unpark();
});
let thread_0 = current();
spawn(move || {
thread_0.unpark();
});
while !FLAG.load(Ordering::Relaxed) {
park();
}
}
```