rust-lang/rust — pull request #19673 by alexcrichton (2014-12-09 22:39:59+00:00)
Title: std: Stabilize the std::hash module

This commit aims to stabilize the `std::hash` module by standardizing on its
hashing interface while rationalizing the current usage with the `HashMap` and
`HashSet` types. The primary goal of this slight redesign is to separate the
concepts of a hasher's state from a hashing algorithm itself.

The primary change of this commit is to separate the `Hasher` trait into a
`Hasher` and a `HashState` trait. Conceptually the old `Hasher` trait was
actually just a factory for various states, but hashing had very little control
over how these states were used. Additionally the old `Hasher` trait was
actually fairly unrelated to hashing.

This commit redesigns the existing `Hasher` trait to match what the notion of a
`Hasher` normally implies with the following definition:

trait Hasher: Writer {
type Output;

fn reset(&mut self);
fn finish(&self) -> Output;
}

Note that the `Output` associated type is currently a type parameter due to
associated types not being fully implemented yet. This new `Hasher` trait
emphasizes that all hashers are sinks for bytes, and hashing algorithms may
produce outputs other than a `u64`, so a the output type is made generic.

With this definition, the old `Hasher` trait is realized as a new `HashState`
trait in the `collections::hash_state` module as an experimental addition for
now. The current definition looks like:

trait HashState {
type H: Hasher;
fn hasher(&self) -> H;
}

Note that the `H` associated type (along with its `O` output) are both type
parameters on the `HashState` trait due to the current limitations of associated
types. The purpose of this trait is to emphasize that the one piece of
functionality for implementors is that new instances of `Hasher` can be created.
This conceptually represents the two keys from which more instances of a
`SipHasher` can be created, and a `HashState` is what's stored in a `HashMap`,
not a `Hasher`.

Implementors of custom hash algorithms should implement the `Hasher` trait, and
only hash algorithms intended for use in hash maps need to implement or worry
about the `HashState` trait.

Some other stability decision made for the `std::hash` module are:

* The name of the module, hash, is `#![stable]`
* The `Hash` and `Hasher` traits are `#[unstable]` due to type parameters that
want to be associated types.
* The `Writer` trait remains `#[experimental]` as it's intended to be replaced
with an `io::Writer` (more details soon).
* The top-level `hash` function is `#[unstable]` as it is intended to be generic
over the hashing algorithm instead of hardwired to `SipHasher`
* The inner `sip` module is now private as its one export, `SipHasher` is
reexported in the `hash` module.

There are many breaking changes outlined above, and as a result this commit is
a:

[breaking-change]