Skip to content

Commit

Permalink
Remove hasher_prefixfree_extras unstable feature
Browse files Browse the repository at this point in the history
**Description**
Remove last nightly feature, `hasher_prefixfree_extras` and replace with
copy from the standard library implementation.

**Motivation**
This change should allow us to compile the crate on stable, part of the
work tracked in issue #20.

**Testing Done**
 - `cargo test`
 - `cargo clippy`
 - `cargo fmt`
  • Loading branch information
Declan Kelly committed Nov 21, 2022
1 parent 6e879e8 commit c58160c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/collections/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ impl<V> FromIterator<(Box<[u8]>, V)> for TreeMap<V> {

impl<V: Hash> Hash for TreeMap<V> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_length_prefix(self.num_entries);
crate::nightly_rust_apis::hasher_write_length_prefix(state, self.num_entries);
for elt in self {
elt.hash(state);
}
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// TODO(#20): Use rust stable distribution, remove usage of nightly features
#![feature(hasher_prefixfree_extras)]
#![allow(unstable_name_collisions)]
#![deny(
missing_docs,
Expand Down
30 changes: 30 additions & 0 deletions src/nightly_rust_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,33 @@ pub unsafe fn non_null_get_unchecked_mut<T>(data: NonNull<[T]>, index: usize) ->

unsafe { NonNull::new_unchecked(data.as_ptr().cast::<T>().add(index)) }
}

/// Writes a length prefix into this hasher, as part of being prefix-free.
///
/// If you're implementing [`Hash`] for a custom collection, call this before
/// writing its contents to this `Hasher`. That way
/// `(collection![1, 2, 3], collection![4, 5])` and
/// `(collection![1, 2], collection![3, 4, 5])` will provide different
/// sequences of values to the `Hasher`
///
/// The `impl<T> Hash for [T]` includes a call to this method, so if you're
/// hashing a slice (or array or vector) via its `Hash::hash` method,
/// you should **not** call this yourself.
///
/// This method is only for providing domain separation. If you want to
/// hash a `usize` that represents part of the *data*, then it's important
/// that you pass it to [`Hasher::write_usize`] instead of to this method.
///
/// # Note to Implementers
///
/// If you've decided that your `Hasher` is willing to be susceptible to
/// Hash-DoS attacks, then you might consider skipping hashing some or all
/// of the `len` provided in the name of increased performance.
///
/// **This is a unstable API copied from the Rust standard library, tracking
/// issue is [#96762][issue-96762]**
///
/// [issue-96762]: https://github.com/rust-lang/rust/issues/96762
pub fn hasher_write_length_prefix<H: std::hash::Hasher>(state: &mut H, num_entries: usize) {
state.write_usize(num_entries);
}

0 comments on commit c58160c

Please sign in to comment.