Implement Hash for raw pointers to unsized types

This commit is contained in:
Matt Brubeck 2017-10-23 14:21:00 -07:00
parent 4c053db233
commit c2c1910d69
2 changed files with 32 additions and 4 deletions

View File

@ -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);
}
}
}
}

View File

@ -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 }