|
57 | 57 | //! assert_ne!(ByAddress(&v[0..4]), ByAddress(&v[0..2])); // Same address, different length. |
58 | 58 | //! ``` |
59 | 59 | //! |
60 | | -//! However, due to limitations of safe Rust, hashing takes only the data address into account. |
61 | | -//! **This may cause performance problems if you use slices as keys in a by-address HashMap or |
62 | | -//! HashSet.** It won't cause correctness bugs, but it may cause a high rate of hash collisions if |
63 | | -//! the keys include many slices with the same starting points but different lengths. |
64 | | -//! |
65 | | -//! ``` |
66 | | -//! # use by_address::ByAddress; |
67 | | -//! # use std::collections::hash_map::DefaultHasher; |
68 | | -//! # use std::hash::{Hash, Hasher}; |
69 | | -//! # |
70 | | -//! fn hash<T: Hash>(t: T) -> u64 { |
71 | | -//! let mut s = DefaultHasher::new(); |
72 | | -//! t.hash(&mut s); |
73 | | -//! s.finish() |
74 | | -//! } |
75 | | -//! |
76 | | -//! let v = [1, 2, 3, 4]; |
77 | | -//! assert_eq!(hash(ByAddress(&v[0..4])), |
78 | | -//! hash(ByAddress(&v[0..2]))); // Uh-oh! |
79 | | -//! ``` |
80 | | -//! |
81 | 60 | //! This crate does not depend on libstd, so it can be used in [`no_std`] projects. |
82 | 61 | //! |
83 | 62 | //! [`no_std`]: https://doc.rust-lang.org/book/first-edition/using-rust-without-the-standard-library.html |
@@ -132,9 +111,7 @@ impl<T> PartialOrd for ByAddress<T> where T: ?Sized + Deref { |
132 | 111 | /// Raw pointer hashing |
133 | 112 | impl<T> Hash for ByAddress<T> where T: ?Sized + Deref { |
134 | 113 | fn hash<H: Hasher>(&self, state: &mut H) { |
135 | | - // FIXME: For fat pointers to dynamically-sized types, this discards the extra data (vtable |
136 | | - // pointer or length), so it may have a high collision rate in certain cases. |
137 | | - (self.addr() as *const ()).hash(state) |
| 114 | + self.addr().hash(state) |
138 | 115 | } |
139 | 116 | } |
140 | 117 |
|
|
0 commit comments