]> git.lizzy.rs Git - rust.git/blob - library/core/tests/hash/mod.rs
Rollup merge of #93613 - crlf0710:rename_to_async_iter, r=yaahc
[rust.git] / library / core / tests / hash / mod.rs
1 mod sip;
2
3 use std::default::Default;
4 use std::hash::{BuildHasher, Hash, Hasher};
5 use std::rc::Rc;
6
7 struct MyHasher {
8     hash: u64,
9 }
10
11 impl Default for MyHasher {
12     fn default() -> MyHasher {
13         MyHasher { hash: 0 }
14     }
15 }
16
17 impl Hasher for MyHasher {
18     fn write(&mut self, buf: &[u8]) {
19         for byte in buf {
20             self.hash += *byte as u64;
21         }
22     }
23     fn finish(&self) -> u64 {
24         self.hash
25     }
26 }
27
28 #[test]
29 fn test_writer_hasher() {
30     fn hash<T: Hash>(t: &T) -> u64 {
31         let mut s = MyHasher { hash: 0 };
32         t.hash(&mut s);
33         s.finish()
34     }
35
36     assert_eq!(hash(&()), 0);
37
38     assert_eq!(hash(&5_u8), 5);
39     assert_eq!(hash(&5_u16), 5);
40     assert_eq!(hash(&5_u32), 5);
41     assert_eq!(hash(&5_u64), 5);
42     assert_eq!(hash(&5_usize), 5);
43
44     assert_eq!(hash(&5_i8), 5);
45     assert_eq!(hash(&5_i16), 5);
46     assert_eq!(hash(&5_i32), 5);
47     assert_eq!(hash(&5_i64), 5);
48     assert_eq!(hash(&5_isize), 5);
49
50     assert_eq!(hash(&false), 0);
51     assert_eq!(hash(&true), 1);
52
53     assert_eq!(hash(&'a'), 97);
54
55     let s: &str = "a";
56     assert_eq!(hash(&s), 97 + 0xFF);
57     let s: Box<str> = String::from("a").into_boxed_str();
58     assert_eq!(hash(&s), 97 + 0xFF);
59     let s: Rc<&str> = Rc::new("a");
60     assert_eq!(hash(&s), 97 + 0xFF);
61     let cs: &[u8] = &[1, 2, 3];
62     assert_eq!(hash(&cs), 9);
63     let cs: Box<[u8]> = Box::new([1, 2, 3]);
64     assert_eq!(hash(&cs), 9);
65     let cs: Rc<[u8]> = Rc::new([1, 2, 3]);
66     assert_eq!(hash(&cs), 9);
67
68     let ptr = 5_usize as *const i32;
69     assert_eq!(hash(&ptr), 5);
70
71     let ptr = 5_usize as *mut i32;
72     assert_eq!(hash(&ptr), 5);
73
74     if cfg!(miri) {
75         // Miri cannot hash pointers
76         return;
77     }
78
79     let cs: &mut [u8] = &mut [1, 2, 3];
80     let ptr = cs.as_ptr();
81     let slice_ptr = cs as *const [u8];
82     assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
83
84     let slice_ptr = cs as *mut [u8];
85     assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
86 }
87
88 struct Custom {
89     hash: u64,
90 }
91 struct CustomHasher {
92     output: u64,
93 }
94
95 impl Hasher for CustomHasher {
96     fn finish(&self) -> u64 {
97         self.output
98     }
99     fn write(&mut self, _: &[u8]) {
100         panic!()
101     }
102     fn write_u64(&mut self, data: u64) {
103         self.output = data;
104     }
105 }
106
107 impl Default for CustomHasher {
108     fn default() -> CustomHasher {
109         CustomHasher { output: 0 }
110     }
111 }
112
113 impl Hash for Custom {
114     fn hash<H: Hasher>(&self, state: &mut H) {
115         state.write_u64(self.hash);
116     }
117 }
118
119 #[test]
120 fn test_custom_state() {
121     fn hash<T: Hash>(t: &T) -> u64 {
122         let mut c = CustomHasher { output: 0 };
123         t.hash(&mut c);
124         c.finish()
125     }
126
127     assert_eq!(hash(&Custom { hash: 5 }), 5);
128 }
129
130 // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten.
131 // See https://github.com/kripken/emscripten-fastcomp/issues/169
132 #[cfg(not(target_os = "emscripten"))]
133 #[test]
134 fn test_indirect_hasher() {
135     let mut hasher = MyHasher { hash: 0 };
136     {
137         let mut indirect_hasher: &mut dyn Hasher = &mut hasher;
138         5u32.hash(&mut indirect_hasher);
139     }
140     assert_eq!(hasher.hash, 5);
141 }
142
143 #[test]
144 fn test_build_hasher_object_safe() {
145     use std::collections::hash_map::{DefaultHasher, RandomState};
146
147     let _: &dyn BuildHasher<Hasher = DefaultHasher> = &RandomState::new();
148 }
149
150 // just tests by whether or not this compiles
151 fn _build_hasher_default_impl_all_auto_traits<T>() {
152     use std::panic::{RefUnwindSafe, UnwindSafe};
153     fn all_auto_traits<T: Send + Sync + Unpin + UnwindSafe + RefUnwindSafe>() {}
154
155     all_auto_traits::<std::hash::BuildHasherDefault<T>>();
156 }