Skip to content

Commit

Permalink
Move hash module from collections to core
Browse files Browse the repository at this point in the history
  • Loading branch information
sfackler committed Dec 16, 2014
1 parent b497f05 commit 24a8ef6
Show file tree
Hide file tree
Showing 18 changed files with 433 additions and 172 deletions.
9 changes: 9 additions & 0 deletions src/liballoc/boxed.rs
Expand Up @@ -15,6 +15,7 @@ use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
use core::default::Default;
use core::fmt;
use core::hash::{mod, Hash};
use core::kinds::Sized;
use core::mem;
use core::option::Option;
Expand Down Expand Up @@ -93,6 +94,14 @@ impl<Sized? T: Ord> Ord for Box<T> {
}
impl<Sized? T: Eq> Eq for Box<T> {}

impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}


/// Extension methods for an owning `Any` trait object.
#[unstable = "post-DST and coherence changes, this will not be a trait but \
rather a direct `impl` on `Box<Any>`"]
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/lib.rs
Expand Up @@ -64,7 +64,7 @@
html_root_url = "http://doc.rust-lang.org/nightly/")]

#![no_std]
#![feature(lang_items, phase, unsafe_destructor)]
#![feature(lang_items, phase, unsafe_destructor, default_type_params)]

#[phase(plugin, link)]
extern crate core;
Expand Down
9 changes: 9 additions & 0 deletions src/liballoc/rc.rs
Expand Up @@ -147,6 +147,7 @@ use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
use core::default::Default;
use core::fmt;
use core::hash::{mod, Hash};
use core::kinds::marker;
use core::mem::{transmute, min_align_of, size_of, forget};
use core::ops::{Deref, Drop};
Expand Down Expand Up @@ -594,6 +595,14 @@ impl<T: Ord> Ord for Rc<T> {
fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
}

// FIXME (#18248) Make `T` `Sized?`
impl<S: hash::Writer, T: Hash<S>> Hash<S> for Rc<T> {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}

#[experimental = "Show is experimental."]
impl<T: fmt::Show> fmt::Show for Rc<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down
3 changes: 1 addition & 2 deletions src/libcollections/lib.rs
Expand Up @@ -67,7 +67,6 @@ pub mod slice;
pub mod str;
pub mod string;
pub mod vec;
pub mod hash;
pub mod vec_map;

pub mod bitv {
Expand Down Expand Up @@ -116,5 +115,5 @@ mod std {
pub use core::clone; // deriving(Clone)
pub use core::cmp; // deriving(Eq, Ord, etc.)
pub use core::kinds; // deriving(Copy)
pub use hash; // deriving(Hash)
pub use core::hash; // deriving(Hash)
}
2 changes: 1 addition & 1 deletion src/libcollections/str.rs
Expand Up @@ -60,10 +60,10 @@ use self::DecompositionType::*;
use core::borrow::{BorrowFrom, Cow, ToOwned};
use core::default::Default;
use core::fmt;
use core::hash;
use core::cmp;
use core::iter::AdditiveIterator;

use hash;
use ring_buf::RingBuf;
use string::String;
use unicode;
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/string.rs
Expand Up @@ -17,13 +17,13 @@ use core::prelude::*;
use core::borrow::{Cow, IntoCow};
use core::default::Default;
use core::fmt;
use core::hash;
use core::mem;
use core::ptr;
use core::ops;
// FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
use core::raw::Slice as RawSlice;

use hash;
use slice::CloneSliceExt;
use str;
use str::{CharRange, CowString, FromStr, StrAllocating, Owned};
Expand Down
8 changes: 8 additions & 0 deletions src/libcollections/vec.rs
Expand Up @@ -20,6 +20,7 @@ use core::borrow::{Cow, IntoCow};
use core::cmp::max;
use core::default::Default;
use core::fmt;
use core::hash::{mod, Hash};
use core::kinds::marker::{ContravariantLifetime, InvariantType};
use core::kinds::Sized;
use core::mem;
Expand Down Expand Up @@ -619,6 +620,13 @@ impl<T: Ord> Ord for Vec<T> {
}
}

impl<S: hash::Writer, T: Hash<S>> Hash<S> for Vec<T> {
#[inline]
fn hash(&self, state: &mut S) {
self.as_slice().hash(state);
}
}

// FIXME: #13996: need a way to mark the return value as `noalias`
#[inline(never)]
unsafe fn alloc_or_realloc<T>(ptr: *mut T, old_size: uint, size: uint) -> *mut T {
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/vec_map.rs
Expand Up @@ -17,12 +17,12 @@ use core::prelude::*;

use core::default::Default;
use core::fmt;
use core::hash::{Hash, Writer};
use core::iter;
use core::iter::{Enumerate, FilterMap};
use core::mem::replace;
use core::ops::FnOnce;

use hash::{Hash, Writer};
use {vec, slice};
use vec::Vec;

Expand Down Expand Up @@ -642,7 +642,7 @@ pub type MoveItems<V> = FilterMap<
mod test_map {
use std::prelude::*;
use vec::Vec;
use hash::hash;
use core::hash::hash;

use super::VecMap;

Expand Down
164 changes: 7 additions & 157 deletions src/libcollections/hash/mod.rs → src/libcore/hash/mod.rs
Expand Up @@ -61,16 +61,12 @@

#![allow(unused_must_use)]

use core::prelude::*;
use prelude::*;

use alloc::boxed::Box;
use alloc::rc::Rc;
use core::borrow::{Cow, ToOwned};
use core::intrinsics::TypeId;
use core::mem;
use core::num::Int;

use vec::Vec;
use borrow::{Cow, ToOwned};
use intrinsics::TypeId;
use mem;
use num::Int;

/// Reexport the `sip::hash` function as our default hasher.
pub use self::sip::hash as hash;
Expand All @@ -92,6 +88,7 @@ pub trait Hasher<S> {
fn hash<Sized? T: Hash<S>>(&self, value: &T) -> u64;
}

#[allow(missing_docs)]
pub trait Writer {
fn write(&mut self, bytes: &[u8]);
}
Expand All @@ -103,7 +100,7 @@ macro_rules! impl_hash {
impl<S: Writer> Hash<S> for $ty {
#[inline]
fn hash(&self, state: &mut S) {
let a: [u8, ..::core::$ty::BYTES] = unsafe {
let a: [u8, ..::$ty::BYTES] = unsafe {
mem::transmute((*self as $uty).to_le() as $ty)
};
state.write(a.as_slice())
Expand Down Expand Up @@ -197,13 +194,6 @@ impl<S: Writer, T: Hash<S>> Hash<S> for [T] {
}


impl<S: Writer, T: Hash<S>> Hash<S> for Vec<T> {
#[inline]
fn hash(&self, state: &mut S) {
self.as_slice().hash(state);
}
}

impl<'a, S: Writer, Sized? T: Hash<S>> Hash<S> for &'a T {
#[inline]
fn hash(&self, state: &mut S) {
Expand All @@ -218,36 +208,6 @@ impl<'a, S: Writer, Sized? T: Hash<S>> Hash<S> for &'a mut T {
}
}

impl<S: Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}

// FIXME (#18248) Make `T` `Sized?`
impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}

impl<S: Writer, T: Hash<S>> Hash<S> for Option<T> {
#[inline]
fn hash(&self, state: &mut S) {
match *self {
Some(ref x) => {
0u8.hash(state);
x.hash(state);
}
None => {
1u8.hash(state);
}
}
}
}

impl<S: Writer, T> Hash<S> for *const T {
#[inline]
fn hash(&self, state: &mut S) {
Expand All @@ -273,119 +233,9 @@ impl<S: Writer> Hash<S> for TypeId {
}
}

impl<S: Writer, T: Hash<S>, U: Hash<S>> Hash<S> for Result<T, U> {
#[inline]
fn hash(&self, state: &mut S) {
match *self {
Ok(ref t) => { 1u.hash(state); t.hash(state); }
Err(ref t) => { 2u.hash(state); t.hash(state); }
}
}
}

impl<'a, T, Sized? B, S> Hash<S> for Cow<'a, T, B> where B: Hash<S> + ToOwned<T> {
#[inline]
fn hash(&self, state: &mut S) {
Hash::hash(&**self, state)
}
}

//////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod tests {
use core::kinds::Sized;
use std::mem;

use slice::SliceExt;
use super::{Hash, Hasher, Writer};

struct MyWriterHasher;

impl Hasher<MyWriter> for MyWriterHasher {
fn hash<Sized? T: Hash<MyWriter>>(&self, value: &T) -> u64 {
let mut state = MyWriter { hash: 0 };
value.hash(&mut state);
state.hash
}
}

struct MyWriter {
hash: u64,
}

impl Writer for MyWriter {
// Most things we'll just add up the bytes.
fn write(&mut self, buf: &[u8]) {
for byte in buf.iter() {
self.hash += *byte as u64;
}
}
}

#[test]
fn test_writer_hasher() {
use alloc::boxed::Box;

let hasher = MyWriterHasher;

assert_eq!(hasher.hash(&()), 0);

assert_eq!(hasher.hash(&5u8), 5);
assert_eq!(hasher.hash(&5u16), 5);
assert_eq!(hasher.hash(&5u32), 5);
assert_eq!(hasher.hash(&5u64), 5);
assert_eq!(hasher.hash(&5u), 5);

assert_eq!(hasher.hash(&5i8), 5);
assert_eq!(hasher.hash(&5i16), 5);
assert_eq!(hasher.hash(&5i32), 5);
assert_eq!(hasher.hash(&5i64), 5);
assert_eq!(hasher.hash(&5i), 5);

assert_eq!(hasher.hash(&false), 0);
assert_eq!(hasher.hash(&true), 1);

assert_eq!(hasher.hash(&'a'), 97);

let s: &str = "a";
assert_eq!(hasher.hash(& s), 97 + 0xFF);
// FIXME (#18283) Enable test
//let s: Box<str> = box "a";
//assert_eq!(hasher.hash(& s), 97 + 0xFF);
let cs: &[u8] = &[1u8, 2u8, 3u8];
assert_eq!(hasher.hash(& cs), 9);
let cs: Box<[u8]> = box [1u8, 2u8, 3u8];
assert_eq!(hasher.hash(& cs), 9);

// FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>

unsafe {
let ptr: *const int = mem::transmute(5i);
assert_eq!(hasher.hash(&ptr), 5);
}

unsafe {
let ptr: *mut int = mem::transmute(5i);
assert_eq!(hasher.hash(&ptr), 5);
}
}

struct Custom {
hash: u64
}

impl Hash<u64> for Custom {
fn hash(&self, state: &mut u64) {
*state = self.hash;
}
}

#[test]
fn test_custom_state() {
let custom = Custom { hash: 5 };
let mut state = 0;
custom.hash(&mut state);
assert_eq!(state, 5);
}
}
5 changes: 2 additions & 3 deletions src/libcollections/hash/sip.rs → src/libcore/hash/sip.rs
Expand Up @@ -24,9 +24,8 @@
//! As such, all cryptographic uses of this implementation are strongly
//! discouraged.

use core::prelude::*;

use core::default::Default;
use prelude::*;
use default::Default;

use super::{Hash, Hasher, Writer};

Expand Down
2 changes: 2 additions & 0 deletions src/libcore/lib.rs
Expand Up @@ -121,6 +121,7 @@ pub mod simd;
pub mod slice;
pub mod str;
pub mod tuple;
pub mod hash;
// FIXME #15320: primitive documentation needs top-level modules, this
// should be `core::tuple::unit`.
#[path = "tuple/unit.rs"]
Expand All @@ -142,4 +143,5 @@ mod std {
pub use kinds;
pub use option;
pub use fmt;
pub use hash;
}
2 changes: 1 addition & 1 deletion src/libcore/option.rs
Expand Up @@ -164,7 +164,7 @@ use ops::{Deref, FnOnce};
// which basically means it must be `Option`.

/// The `Option` type.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Hash)]
#[stable]
pub enum Option<T> {
/// No value
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/result.rs
Expand Up @@ -244,7 +244,7 @@ use ops::{FnMut, FnOnce};
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
///
/// See the [`std::result`](index.html) module documentation for details.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Hash)]
#[must_use]
#[stable]
pub enum Result<T, E> {
Expand Down

7 comments on commit 24a8ef6

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at sfackler@24a8ef6

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging sfackler/rust/core-hash = 24a8ef6 into auto

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

status: {"merge_sha": "66c297d847ce06a8982d4d322221b17a3cd04f90"}

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sfackler/rust/core-hash = 24a8ef6 merged ok, testing candidate = 66c297d

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 66c297d

@bors
Copy link
Contributor

@bors bors commented on 24a8ef6 Dec 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 66c297d

Please sign in to comment.