When inserting using the entry API and the robin-hood case is hit,
we currently return using the incorrect index, which in turn
returns a reference to the wrong entry in the map, causing
undefined behaviour in the API.
335: Implement retain for IndexSet/IndexMap. r=korken89 a=jeandudey
Needed to remove IndexMap/IndexSet elements while iterating over it.
Co-authored-by: Jean-Pierre De Jesus DIAZ <me@jeandudey.tech>
this release of `hash32` has the advantage that 32-bit hashers can be used to hash types that
implement the `core:#️⃣:Hash` trait removing the need for the `hash32::Hash` implementations in
this crate and the uses of the `#[derive(Hash32)]` macro (which did not support enums) in dependent
crates
with this change the following code works
``` rust
// NOTE no derive(Hash32)
struct Int(i32);
let mut x = FnvIndexSet::<_, 4>::default();
let _ = x.insert(Int(0));
```
this change is technically a breaking change because the following code is no longer accepted
``` rust
// assume this type comes from a dependency
// NOTE no derive(Hash)
struct Int(i32);
let mut x = FnvIndexSet::<_, 4>::default();
let _ = x.insert(Int(0)); // error: does not implement Hash
```
The fixes in #280 missed one instance of UB. The get_unchecked_mut
inside VacantEntry::Insert can be out of bounds of the initialized
region of the backing Vec. When that happens, the call is UB. This is
detected both by the standard library's debug assertions which can be
enabled with -Zbuild-std and with Miri but only with
-Zmiri-tag-raw-pointers.
This also adds inherent as_ptr and as_mut_ptr methods to Vec which
shadow those provided by the Deref to a slice. Without this shadowing,
the change from get_unchecked_mut to as_mut_ptr.add wouldn't actually
fix the problem identified by the debug assertions or Miri, it just
hides it from the debug assertions. The core problem is that references
narrow provenance, so if we want to access outside of the initialized
region of a Vec we need to get a pointer to the array without passing
through a reference to the initialized region first. The pointers from
these shadowing methods can be used to access anywhere in the allocation,
whereas vec.as_slice().as_ptr() would be UB to use for access into the
uninitialized region.
vec passes tests
vec passes tests with docs as well (besides one with FromIter)
vec passes tests with docs as well (besides one with FromIter)
exposing full API
passing all current tests
starting with string
string test passes mostly
string test passes
ufmt passes
TODO removed
binary_heap wip
binary_heap passes tests
sealed passes
spsc wip
spsc wip2
split wip3
spcs and split passes --lib tests
spcs and split passes --lib tests
spcs and split passes --lib tests
spcs and split passes all tests (doc + lib)
indexmap wip
indexmap passes --lib test
indexmap passes all tests (lib + doc)
indexset passes all tests (lib + doc)
indexset passes all tests (lib + doc)
linear map wip
linear map all test (lib + doc) passes, drop not tested, into_iter(mut self) not implemented
history buffer all test pass (doc + lib), Copy instead of clone atm
serde does not work
pool works, serde still not
serde wip
serde wip
serde wip
serde wip