|
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