Skip to content

Commit 1ca9e78

Browse files
committed
Hash fat pointers
This fixes the problem where only the "data" part of a fat pointer could be hashed. Depends on rust-lang/rust#45483. Fixes #2.
1 parent df57213 commit 1ca9e78

File tree

2 files changed

+2
-25
lines changed

2 files changed

+2
-25
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "by_address"
3-
version = "1.0.3"
3+
version = "1.0.4"
44
authors = ["Matt Brubeck <[email protected]>"]
55
license = "MIT / Apache-2.0"
66
description = "Wrapper for comparing and hashing pointers by address"

src/lib.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,6 @@
5757
//! assert_ne!(ByAddress(&v[0..4]), ByAddress(&v[0..2])); // Same address, different length.
5858
//! ```
5959
//!
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-
//!
8160
//! This crate does not depend on libstd, so it can be used in [`no_std`] projects.
8261
//!
8362
//! [`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 {
132111
/// Raw pointer hashing
133112
impl<T> Hash for ByAddress<T> where T: ?Sized + Deref {
134113
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)
138115
}
139116
}
140117

0 commit comments

Comments
 (0)