|  | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT | 
|  | // file at the top-level directory of this distribution and at | 
|  | // http://rust-lang.org/COPYRIGHT. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | 
|  | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | 
|  | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | 
|  | // option. This file may not be copied, modified, or distributed | 
|  | // except according to those terms. | 
|  |  | 
|  | #![allow(non_camel_case_types)] | 
|  |  | 
|  | #[cfg(feature = "use_core")] | 
|  | extern crate core; | 
|  |  | 
|  | #[macro_use] | 
|  | extern crate derivative; | 
|  |  | 
|  | use std::hash::{Hash, Hasher}; | 
|  | use std::collections::hash_map::DefaultHasher; | 
|  |  | 
|  | #[derive(Derivative)] | 
|  | #[derivative(Hash)] | 
|  | struct Person { | 
|  | id: u16, | 
|  | name: String, | 
|  | phone: u64, | 
|  | } | 
|  |  | 
|  | // test for hygiene name collisions | 
|  | #[derive(Derivative)] | 
|  | #[derivative(Hash)] struct __H__H; | 
|  | #[derive(Derivative)] | 
|  | #[allow(dead_code)] #[derivative(Hash)] struct Collision<__H> ( __H ); | 
|  | // TODO(rustc) #[derivative(Hash)] enum Collision<__H> { __H { __H__H: __H } } | 
|  |  | 
|  | #[derive(Derivative)] | 
|  | #[derivative(Hash)] | 
|  | enum E { A=1, B } | 
|  |  | 
|  | fn hash<T: Hash>(t: &T) -> u64 { | 
|  | let mut s = DefaultHasher::new(); | 
|  | t.hash(&mut s); | 
|  | s.finish() | 
|  | } | 
|  |  | 
|  | struct FakeHasher<'a>(&'a mut Vec<u8>); | 
|  | impl<'a> Hasher for FakeHasher<'a> { | 
|  | fn finish(&self) -> u64 { | 
|  | unimplemented!() | 
|  | } | 
|  |  | 
|  | fn write(&mut self, bytes: &[u8]) { | 
|  | self.0.extend(bytes); | 
|  | } | 
|  | } | 
|  |  | 
|  | fn fake_hash(v: &mut Vec<u8>, e: E) { | 
|  | e.hash(&mut FakeHasher(v)); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn main() { | 
|  | let person1 = Person { | 
|  | id: 5, | 
|  | name: "Janet".to_string(), | 
|  | phone: 555_666_7777 | 
|  | }; | 
|  | let person2 = Person { | 
|  | id: 5, | 
|  | name: "Bob".to_string(), | 
|  | phone: 555_666_7777 | 
|  | }; | 
|  | assert_eq!(hash(&person1), hash(&person1)); | 
|  | assert!(hash(&person1) != hash(&person2)); | 
|  |  | 
|  | // test #21714 | 
|  | let mut va = vec![]; | 
|  | let mut vb = vec![]; | 
|  | fake_hash(&mut va, E::A); | 
|  | fake_hash(&mut vb, E::B); | 
|  | assert!(va != vb); | 
|  | } |