]> git.proxmox.com Git - rustc.git/blame - src/libcore/hash/mod.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / libcore / hash / mod.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Generic hashing support.
12//!
13//! This module provides a generic way to compute the hash of a value. The
14//! simplest way to make a type hashable is to use `#[derive(Hash)]`:
15//!
16//! # Examples
17//!
18//! ```rust
cc61c64b
XL
19//! use std::collections::hash_map::DefaultHasher;
20//! use std::hash::{Hash, Hasher};
1a4d82fc
JJ
21//!
22//! #[derive(Hash)]
23//! struct Person {
c34b1796 24//! id: u32,
1a4d82fc
JJ
25//! name: String,
26//! phone: u64,
27//! }
28//!
cc61c64b
XL
29//! let person1 = Person {
30//! id: 5,
31//! name: "Janet".to_string(),
32//! phone: 555_666_7777,
33//! };
34//! let person2 = Person {
35//! id: 5,
36//! name: "Bob".to_string(),
37//! phone: 555_666_7777,
38//! };
1a4d82fc 39//!
cc61c64b 40//! assert!(calculate_hash(&person1) != calculate_hash(&person2));
e9174d1e 41//!
cc61c64b
XL
42//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
43//! let mut s = DefaultHasher::new();
e9174d1e
SL
44//! t.hash(&mut s);
45//! s.finish()
46//! }
1a4d82fc
JJ
47//! ```
48//!
49//! If you need more control over how a value is hashed, you need to implement
c30ab7b3
SL
50//! the [`Hash`] trait:
51//!
52//! [`Hash`]: trait.Hash.html
1a4d82fc
JJ
53//!
54//! ```rust
cc61c64b
XL
55//! use std::collections::hash_map::DefaultHasher;
56//! use std::hash::{Hash, Hasher};
1a4d82fc
JJ
57//!
58//! struct Person {
c34b1796 59//! id: u32,
cc61c64b 60//! # #[allow(dead_code)]
1a4d82fc
JJ
61//! name: String,
62//! phone: u64,
63//! }
64//!
85aaf69f
SL
65//! impl Hash for Person {
66//! fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
67//! self.id.hash(state);
68//! self.phone.hash(state);
69//! }
70//! }
71//!
cc61c64b
XL
72//! let person1 = Person {
73//! id: 5,
74//! name: "Janet".to_string(),
75//! phone: 555_666_7777,
76//! };
77//! let person2 = Person {
78//! id: 5,
79//! name: "Bob".to_string(),
80//! phone: 555_666_7777,
81//! };
1a4d82fc 82//!
cc61c64b 83//! assert_eq!(calculate_hash(&person1), calculate_hash(&person2));
e9174d1e 84//!
cc61c64b
XL
85//! fn calculate_hash<T: Hash>(t: &T) -> u64 {
86//! let mut s = DefaultHasher::new();
e9174d1e
SL
87//! t.hash(&mut s);
88//! s.finish()
89//! }
1a4d82fc
JJ
90//! ```
91
85aaf69f
SL
92#![stable(feature = "rust1", since = "1.0.0")]
93
54a0048b 94use fmt;
9cc50fc6 95use marker;
85aaf69f 96use mem;
1a4d82fc 97
92a42be0 98#[stable(feature = "rust1", since = "1.0.0")]
9e0c209e 99#[allow(deprecated)]
1a4d82fc
JJ
100pub use self::sip::SipHasher;
101
041b39d2 102#[unstable(feature = "sip_hash_13", issue = "34767")]
9e0c209e 103#[allow(deprecated)]
3157f602
XL
104pub use self::sip::{SipHasher13, SipHasher24};
105
1a4d82fc
JJ
106mod sip;
107
108/// A hashable type.
109///
cc61c64b
XL
110/// Types implementing `Hash` are able to be [`hash`]ed with an instance of
111/// [`Hasher`].
c34b1796 112///
cc61c64b 113/// ## Implementing `Hash`
c34b1796 114///
cc61c64b
XL
115/// You can derive `Hash` with `#[derive(Hash)]` if all fields implement `Hash`.
116/// The resulting hash will be the combination of the values from calling
117/// [`hash`] on each field.
92a42be0 118///
cc61c64b
XL
119/// ```
120/// #[derive(Hash)]
121/// struct Rustacean {
122/// name: String,
123/// country: String,
124/// }
125/// ```
3157f602 126///
cc61c64b
XL
127/// If you need more control over how a value is hashed, you can of course
128/// implement the `Hash` trait yourself:
3157f602
XL
129///
130/// ```
131/// use std::hash::{Hash, Hasher};
132///
133/// struct Person {
134/// id: u32,
135/// name: String,
136/// phone: u64,
137/// }
138///
139/// impl Hash for Person {
140/// fn hash<H: Hasher>(&self, state: &mut H) {
141/// self.id.hash(state);
142/// self.phone.hash(state);
143/// }
144/// }
145/// ```
c30ab7b3 146///
cc61c64b
XL
147/// ## `Hash` and `Eq`
148///
149/// When implementing both `Hash` and [`Eq`], it is important that the following
150/// property holds:
151///
152/// ```text
153/// k1 == k2 -> hash(k1) == hash(k2)
154/// ```
155///
156/// In other words, if two keys are equal, their hashes must also be equal.
157/// [`HashMap`] and [`HashSet`] both rely on this behavior.
158///
159/// Thankfully, you won't need to worry about upholding this property when
160/// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
161///
c30ab7b3 162/// [`Eq`]: ../../std/cmp/trait.Eq.html
cc61c64b 163/// [`Hasher`]: trait.Hasher.html
c30ab7b3
SL
164/// [`HashMap`]: ../../std/collections/struct.HashMap.html
165/// [`HashSet`]: ../../std/collections/struct.HashSet.html
cc61c64b 166/// [`hash`]: #tymethod.hash
85aaf69f
SL
167#[stable(feature = "rust1", since = "1.0.0")]
168pub trait Hash {
cc61c64b
XL
169 /// Feeds this value into the given [`Hasher`].
170 ///
171 /// # Examples
172 ///
173 /// ```
174 /// use std::collections::hash_map::DefaultHasher;
175 /// use std::hash::{Hash, Hasher};
176 ///
177 /// let mut hasher = DefaultHasher::new();
178 /// 7920.hash(&mut hasher);
179 /// println!("Hash is {:x}!", hasher.finish());
180 /// ```
181 ///
182 /// [`Hasher`]: trait.Hasher.html
85aaf69f
SL
183 #[stable(feature = "rust1", since = "1.0.0")]
184 fn hash<H: Hasher>(&self, state: &mut H);
185
cc61c64b
XL
186 /// Feeds a slice of this type into the given [`Hasher`].
187 ///
188 /// # Examples
189 ///
190 /// ```
191 /// use std::collections::hash_map::DefaultHasher;
192 /// use std::hash::{Hash, Hasher};
193 ///
194 /// let mut hasher = DefaultHasher::new();
195 /// let numbers = [6, 28, 496, 8128];
196 /// Hash::hash_slice(&numbers, &mut hasher);
197 /// println!("Hash is {:x}!", hasher.finish());
198 /// ```
199 ///
200 /// [`Hasher`]: trait.Hasher.html
c1a9b12d 201 #[stable(feature = "hash_slice", since = "1.3.0")]
b039eaaf
SL
202 fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
203 where Self: Sized
204 {
85aaf69f
SL
205 for piece in data {
206 piece.hash(state);
207 }
208 }
1a4d82fc
JJ
209}
210
cc61c64b
XL
211/// A trait for hashing an arbitrary stream of bytes.
212///
213/// Instances of `Hasher` usually represent state that is changed while hashing
214/// data.
215///
216/// `Hasher` provides a fairly basic interface for retrieving the generated hash
217/// (with [`finish`]), and writing integers as well as slices of bytes into an
218/// instance (with [`write`] and [`write_u8`] etc.). Most of the time, `Hasher`
219/// instances are used in conjunction with the [`Hash`] trait.
220///
221/// # Examples
222///
223/// ```
224/// use std::collections::hash_map::DefaultHasher;
225/// use std::hash::Hasher;
226///
227/// let mut hasher = DefaultHasher::new();
228///
229/// hasher.write_u32(1989);
230/// hasher.write_u8(11);
231/// hasher.write_u8(9);
232/// hasher.write(b"Huh?");
233///
234/// println!("Hash is {:x}!", hasher.finish());
235/// ```
236///
237/// [`Hash`]: trait.Hash.html
238/// [`finish`]: #tymethod.finish
239/// [`write`]: #tymethod.write
240/// [`write_u8`]: #method.write_u8
85aaf69f 241#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 242pub trait Hasher {
3b2f2976
XL
243 /// Returns the hash value for the values written so far.
244 ///
245 /// Despite its name, the method does not reset the hasher’s internal
246 /// state. Additional [`write`]s will continue from the current value.
247 /// If you need to start a fresh hash value, you will have to create
248 /// a new hasher.
cc61c64b
XL
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use std::collections::hash_map::DefaultHasher;
254 /// use std::hash::Hasher;
255 ///
256 /// let mut hasher = DefaultHasher::new();
257 /// hasher.write(b"Cool!");
258 ///
259 /// println!("Hash is {:x}!", hasher.finish());
260 /// ```
3b2f2976 261 ///
abe05a73 262 /// [`write`]: #tymethod.write
c34b1796 263 #[stable(feature = "rust1", since = "1.0.0")]
85aaf69f
SL
264 fn finish(&self) -> u64;
265
c30ab7b3 266 /// Writes some data into this `Hasher`.
cc61c64b
XL
267 ///
268 /// # Examples
269 ///
270 /// ```
271 /// use std::collections::hash_map::DefaultHasher;
272 /// use std::hash::Hasher;
273 ///
274 /// let mut hasher = DefaultHasher::new();
275 /// let data = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
276 ///
277 /// hasher.write(&data);
278 ///
279 /// println!("Hash is {:x}!", hasher.finish());
280 /// ```
85aaf69f
SL
281 #[stable(feature = "rust1", since = "1.0.0")]
282 fn write(&mut self, bytes: &[u8]);
283
cc61c64b 284 /// Writes a single `u8` into this hasher.
85aaf69f 285 #[inline]
c1a9b12d 286 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
287 fn write_u8(&mut self, i: u8) {
288 self.write(&[i])
289 }
c30ab7b3 290 /// Writes a single `u16` into this hasher.
85aaf69f 291 #[inline]
c1a9b12d 292 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
293 fn write_u16(&mut self, i: u16) {
294 self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
295 }
c30ab7b3 296 /// Writes a single `u32` into this hasher.
85aaf69f 297 #[inline]
c1a9b12d 298 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
299 fn write_u32(&mut self, i: u32) {
300 self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
301 }
c30ab7b3 302 /// Writes a single `u64` into this hasher.
85aaf69f 303 #[inline]
c1a9b12d 304 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f
SL
305 fn write_u64(&mut self, i: u64) {
306 self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
307 }
32a655c1
SL
308 /// Writes a single `u128` into this hasher.
309 #[inline]
310 #[unstable(feature = "i128", issue = "35118")]
311 fn write_u128(&mut self, i: u128) {
312 self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) })
313 }
c30ab7b3 314 /// Writes a single `usize` into this hasher.
85aaf69f 315 #[inline]
c1a9b12d 316 #[stable(feature = "hasher_write", since = "1.3.0")]
85aaf69f 317 fn write_usize(&mut self, i: usize) {
e9174d1e 318 let bytes = unsafe {
b039eaaf 319 ::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::<usize>())
e9174d1e
SL
320 };
321 self.write(bytes);
85aaf69f
SL
322 }
323
c30ab7b3 324 /// Writes a single `i8` into this hasher.
85aaf69f 325 #[inline]
c1a9b12d 326 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
327 fn write_i8(&mut self, i: i8) {
328 self.write_u8(i as u8)
329 }
c30ab7b3 330 /// Writes a single `i16` into this hasher.
85aaf69f 331 #[inline]
c1a9b12d 332 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
333 fn write_i16(&mut self, i: i16) {
334 self.write_u16(i as u16)
335 }
c30ab7b3 336 /// Writes a single `i32` into this hasher.
85aaf69f 337 #[inline]
c1a9b12d 338 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
339 fn write_i32(&mut self, i: i32) {
340 self.write_u32(i as u32)
341 }
c30ab7b3 342 /// Writes a single `i64` into this hasher.
85aaf69f 343 #[inline]
c1a9b12d 344 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
345 fn write_i64(&mut self, i: i64) {
346 self.write_u64(i as u64)
347 }
32a655c1
SL
348 /// Writes a single `i128` into this hasher.
349 #[inline]
350 #[unstable(feature = "i128", issue = "35118")]
351 fn write_i128(&mut self, i: i128) {
352 self.write_u128(i as u128)
353 }
c30ab7b3 354 /// Writes a single `isize` into this hasher.
85aaf69f 355 #[inline]
c1a9b12d 356 #[stable(feature = "hasher_write", since = "1.3.0")]
b039eaaf
SL
357 fn write_isize(&mut self, i: isize) {
358 self.write_usize(i as usize)
359 }
1a4d82fc
JJ
360}
361
ea8adc8c
XL
362#[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
363impl<'a, H: Hasher + ?Sized> Hasher for &'a mut H {
364 fn finish(&self) -> u64 {
365 (**self).finish()
366 }
367 fn write(&mut self, bytes: &[u8]) {
368 (**self).write(bytes)
369 }
370 fn write_u8(&mut self, i: u8) {
371 (**self).write_u8(i)
372 }
373 fn write_u16(&mut self, i: u16) {
374 (**self).write_u16(i)
375 }
376 fn write_u32(&mut self, i: u32) {
377 (**self).write_u32(i)
378 }
379 fn write_u64(&mut self, i: u64) {
380 (**self).write_u64(i)
381 }
382 fn write_u128(&mut self, i: u128) {
383 (**self).write_u128(i)
384 }
385 fn write_usize(&mut self, i: usize) {
386 (**self).write_usize(i)
387 }
388 fn write_i8(&mut self, i: i8) {
389 (**self).write_i8(i)
390 }
391 fn write_i16(&mut self, i: i16) {
392 (**self).write_i16(i)
393 }
394 fn write_i32(&mut self, i: i32) {
395 (**self).write_i32(i)
396 }
397 fn write_i64(&mut self, i: i64) {
398 (**self).write_i64(i)
399 }
400 fn write_i128(&mut self, i: i128) {
401 (**self).write_i128(i)
402 }
403 fn write_isize(&mut self, i: isize) {
404 (**self).write_isize(i)
405 }
406}
407
cc61c64b
XL
408/// A trait for creating instances of [`Hasher`].
409///
410/// A `BuildHasher` is typically used (e.g. by [`HashMap`]) to create
411/// [`Hasher`]s for each key such that they are hashed independently of one
412/// another, since [`Hasher`]s contain state.
413///
414/// For each instance of `BuildHasher`, the [`Hasher`]s created by
415/// [`build_hasher`] should be identical. That is, if the same stream of bytes
416/// is fed into each hasher, the same output will also be generated.
417///
418/// # Examples
419///
420/// ```
421/// use std::collections::hash_map::RandomState;
422/// use std::hash::{BuildHasher, Hasher};
423///
424/// let s = RandomState::new();
425/// let mut hasher_1 = s.build_hasher();
426/// let mut hasher_2 = s.build_hasher();
9cc50fc6 427///
cc61c64b
XL
428/// hasher_1.write_u32(8128);
429/// hasher_2.write_u32(8128);
430///
431/// assert_eq!(hasher_1.finish(), hasher_2.finish());
432/// ```
433///
434/// [`build_hasher`]: #tymethod.build_hasher
435/// [`Hasher`]: trait.Hasher.html
436/// [`HashMap`]: ../../std/collections/struct.HashMap.html
9cc50fc6
SL
437#[stable(since = "1.7.0", feature = "build_hasher")]
438pub trait BuildHasher {
439 /// Type of the hasher that will be created.
440 #[stable(since = "1.7.0", feature = "build_hasher")]
441 type Hasher: Hasher;
442
443 /// Creates a new hasher.
5bcae85e 444 ///
cc61c64b
XL
445 /// Each call to `build_hasher` on the same instance should produce identical
446 /// [`Hasher`]s.
447 ///
5bcae85e
SL
448 /// # Examples
449 ///
450 /// ```
451 /// use std::collections::hash_map::RandomState;
452 /// use std::hash::BuildHasher;
453 ///
454 /// let s = RandomState::new();
455 /// let new_s = s.build_hasher();
456 /// ```
cc61c64b
XL
457 ///
458 /// [`Hasher`]: trait.Hasher.html
9cc50fc6
SL
459 #[stable(since = "1.7.0", feature = "build_hasher")]
460 fn build_hasher(&self) -> Self::Hasher;
461}
462
cc61c64b
XL
463/// Used to create a default [`BuildHasher`] instance for types that implement
464/// [`Hasher`] and [`Default`].
9cc50fc6 465///
cc61c64b
XL
466/// `BuildHasherDefault<H>` can be used when a type `H` implements [`Hasher`] and
467/// [`Default`], and you need a corresponding [`BuildHasher`] instance, but none is
468/// defined.
469///
470/// Any `BuildHasherDefault` is [zero-sized]. It can be created with
471/// [`default`][method.Default]. When using `BuildHasherDefault` with [`HashMap`] or
472/// [`HashSet`], this doesn't need to be done, since they implement appropriate
473/// [`Default`] instances themselves.
476ff2be
SL
474///
475/// # Examples
476///
477/// Using `BuildHasherDefault` to specify a custom [`BuildHasher`] for
478/// [`HashMap`]:
479///
480/// ```
481/// use std::collections::HashMap;
482/// use std::hash::{BuildHasherDefault, Hasher};
483///
484/// #[derive(Default)]
485/// struct MyHasher;
486///
487/// impl Hasher for MyHasher {
488/// fn write(&mut self, bytes: &[u8]) {
489/// // Your hashing algorithm goes here!
490/// unimplemented!()
491/// }
492///
493/// fn finish(&self) -> u64 {
494/// // Your hashing algorithm goes here!
495/// unimplemented!()
496/// }
497/// }
498///
499/// type MyBuildHasher = BuildHasherDefault<MyHasher>;
500///
501/// let hash_map = HashMap::<u32, u32, MyBuildHasher>::default();
502/// ```
503///
504/// [`BuildHasher`]: trait.BuildHasher.html
505/// [`Default`]: ../default/trait.Default.html
cc61c64b 506/// [method.default]: #method.default
476ff2be 507/// [`Hasher`]: trait.Hasher.html
32a655c1 508/// [`HashMap`]: ../../std/collections/struct.HashMap.html
cc61c64b
XL
509/// [`HashSet`]: ../../std/collections/struct.HashSet.html
510/// [zero-sized]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts
9cc50fc6
SL
511#[stable(since = "1.7.0", feature = "build_hasher")]
512pub struct BuildHasherDefault<H>(marker::PhantomData<H>);
513
54a0048b
SL
514#[stable(since = "1.9.0", feature = "core_impl_debug")]
515impl<H> fmt::Debug for BuildHasherDefault<H> {
516 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
517 f.pad("BuildHasherDefault")
518 }
519}
520
9cc50fc6
SL
521#[stable(since = "1.7.0", feature = "build_hasher")]
522impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> {
523 type Hasher = H;
524
525 fn build_hasher(&self) -> H {
526 H::default()
527 }
528}
529
530#[stable(since = "1.7.0", feature = "build_hasher")]
531impl<H> Clone for BuildHasherDefault<H> {
532 fn clone(&self) -> BuildHasherDefault<H> {
533 BuildHasherDefault(marker::PhantomData)
534 }
535}
536
537#[stable(since = "1.7.0", feature = "build_hasher")]
538impl<H> Default for BuildHasherDefault<H> {
539 fn default() -> BuildHasherDefault<H> {
540 BuildHasherDefault(marker::PhantomData)
541 }
542}
543
1a4d82fc
JJ
544//////////////////////////////////////////////////////////////////////////////
545
1a4d82fc 546mod impls {
9cc50fc6 547 use mem;
85aaf69f
SL
548 use slice;
549 use super::*;
1a4d82fc 550
85aaf69f
SL
551 macro_rules! impl_write {
552 ($(($ty:ident, $meth:ident),)*) => {$(
553 #[stable(feature = "rust1", since = "1.0.0")]
554 impl Hash for $ty {
555 fn hash<H: Hasher>(&self, state: &mut H) {
556 state.$meth(*self)
557 }
558
559 fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
9cc50fc6 560 let newlen = data.len() * mem::size_of::<$ty>();
85aaf69f
SL
561 let ptr = data.as_ptr() as *const u8;
562 state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
1a4d82fc
JJ
563 }
564 }
85aaf69f 565 )*}
1a4d82fc
JJ
566 }
567
85aaf69f
SL
568 impl_write! {
569 (u8, write_u8),
570 (u16, write_u16),
571 (u32, write_u32),
572 (u64, write_u64),
573 (usize, write_usize),
574 (i8, write_i8),
575 (i16, write_i16),
576 (i32, write_i32),
577 (i64, write_i64),
578 (isize, write_isize),
32a655c1
SL
579 (u128, write_u128),
580 (i128, write_i128),
581 }
1a4d82fc 582
85aaf69f
SL
583 #[stable(feature = "rust1", since = "1.0.0")]
584 impl Hash for bool {
585 fn hash<H: Hasher>(&self, state: &mut H) {
586 state.write_u8(*self as u8)
1a4d82fc
JJ
587 }
588 }
589
85aaf69f
SL
590 #[stable(feature = "rust1", since = "1.0.0")]
591 impl Hash for char {
592 fn hash<H: Hasher>(&self, state: &mut H) {
593 state.write_u32(*self as u32)
1a4d82fc
JJ
594 }
595 }
596
85aaf69f
SL
597 #[stable(feature = "rust1", since = "1.0.0")]
598 impl Hash for str {
599 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 600 state.write(self.as_bytes());
85aaf69f 601 state.write_u8(0xff)
1a4d82fc
JJ
602 }
603 }
604
605 macro_rules! impl_hash_tuple {
606 () => (
85aaf69f
SL
607 #[stable(feature = "rust1", since = "1.0.0")]
608 impl Hash for () {
609 fn hash<H: Hasher>(&self, _state: &mut H) {}
1a4d82fc
JJ
610 }
611 );
612
613 ( $($name:ident)+) => (
85aaf69f 614 #[stable(feature = "rust1", since = "1.0.0")]
041b39d2 615 impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
1a4d82fc 616 #[allow(non_snake_case)]
85aaf69f
SL
617 fn hash<S: Hasher>(&self, state: &mut S) {
618 let ($(ref $name,)*) = *self;
619 $($name.hash(state);)*
1a4d82fc
JJ
620 }
621 }
622 );
623 }
624
041b39d2
XL
625 macro_rules! last_type {
626 ($a:ident,) => { $a };
627 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
628 }
629
1a4d82fc
JJ
630 impl_hash_tuple! {}
631 impl_hash_tuple! { A }
632 impl_hash_tuple! { A B }
633 impl_hash_tuple! { A B C }
634 impl_hash_tuple! { A B C D }
635 impl_hash_tuple! { A B C D E }
636 impl_hash_tuple! { A B C D E F }
637 impl_hash_tuple! { A B C D E F G }
638 impl_hash_tuple! { A B C D E F G H }
639 impl_hash_tuple! { A B C D E F G H I }
640 impl_hash_tuple! { A B C D E F G H I J }
641 impl_hash_tuple! { A B C D E F G H I J K }
642 impl_hash_tuple! { A B C D E F G H I J K L }
643
85aaf69f
SL
644 #[stable(feature = "rust1", since = "1.0.0")]
645 impl<T: Hash> Hash for [T] {
646 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc 647 self.len().hash(state);
85aaf69f 648 Hash::hash_slice(self, state)
1a4d82fc
JJ
649 }
650 }
651
652
85aaf69f
SL
653 #[stable(feature = "rust1", since = "1.0.0")]
654 impl<'a, T: ?Sized + Hash> Hash for &'a T {
655 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
656 (**self).hash(state);
657 }
658 }
659
85aaf69f
SL
660 #[stable(feature = "rust1", since = "1.0.0")]
661 impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
662 fn hash<H: Hasher>(&self, state: &mut H) {
1a4d82fc
JJ
663 (**self).hash(state);
664 }
665 }
666
85aaf69f 667 #[stable(feature = "rust1", since = "1.0.0")]
abe05a73 668 impl<T: ?Sized> Hash for *const T {
85aaf69f 669 fn hash<H: Hasher>(&self, state: &mut H) {
abe05a73
XL
670 if mem::size_of::<Self>() == mem::size_of::<usize>() {
671 // Thin pointer
672 state.write_usize(*self as *const () as usize);
673 } else {
674 // Fat pointer
675 let (a, b) = unsafe {
676 *(self as *const Self as *const (usize, usize))
677 };
678 state.write_usize(a);
679 state.write_usize(b);
680 }
1a4d82fc
JJ
681 }
682 }
683
85aaf69f 684 #[stable(feature = "rust1", since = "1.0.0")]
abe05a73 685 impl<T: ?Sized> Hash for *mut T {
85aaf69f 686 fn hash<H: Hasher>(&self, state: &mut H) {
abe05a73
XL
687 if mem::size_of::<Self>() == mem::size_of::<usize>() {
688 // Thin pointer
689 state.write_usize(*self as *const () as usize);
690 } else {
691 // Fat pointer
692 let (a, b) = unsafe {
693 *(self as *const Self as *const (usize, usize))
694 };
695 state.write_usize(a);
696 state.write_usize(b);
697 }
1a4d82fc
JJ
698 }
699 }
700}