Skip to content

Commit

Permalink
Rollup merge of rust-lang#45483 - mbrubeck:hash, r=alexcrichton
Browse files Browse the repository at this point in the history
Implement Hash for raw pointers to unsized types

This is useful for some niche cases, like a hash table of slices or trait objects where the key is the raw pointer.  Example use case: https://docs.rs/by_address
  • Loading branch information
kennytm committed Oct 25, 2017
2 parents 6402797 + c2c1910 commit 86360b7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/libcore/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,16 +665,36 @@ mod impls {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Hash for *const T {
impl<T: ?Sized> Hash for *const T {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self as usize)
if mem::size_of::<Self>() == mem::size_of::<usize>() {
// Thin pointer
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
let (a, b) = unsafe {
*(self as *const Self as *const (usize, usize))
};
state.write_usize(a);
state.write_usize(b);
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Hash for *mut T {
impl<T: ?Sized> Hash for *mut T {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self as usize)
if mem::size_of::<Self>() == mem::size_of::<usize>() {
// Thin pointer
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
let (a, b) = unsafe {
*(self as *const Self as *const (usize, usize))
};
state.write_usize(a);
state.write_usize(b);
}
}
}
}
8 changes: 8 additions & 0 deletions src/libcore/tests/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ fn test_writer_hasher() {

let ptr = 5_usize as *mut i32;
assert_eq!(hash(&ptr), 5);

let cs: &mut [u8] = &mut [1, 2, 3];
let ptr = cs.as_ptr();
let slice_ptr = cs as *const [u8];
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);

let slice_ptr = cs as *mut [u8];
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
}

struct Custom { hash: u64 }
Expand Down

0 comments on commit 86360b7

Please sign in to comment.