From c2c1910d69086827629d37deb5ce6a2febdb36fd Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 23 Oct 2017 14:21:00 -0700 Subject: [PATCH] Implement Hash for raw pointers to unsized types --- src/libcore/hash/mod.rs | 28 ++++++++++++++++++++++++---- src/libcore/tests/hash/mod.rs | 8 ++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index bc1b911cd78cc..b3c11ed1b5ac4 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -665,16 +665,36 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Hash for *const T { + impl Hash for *const T { fn hash(&self, state: &mut H) { - state.write_usize(*self as usize) + if mem::size_of::() == mem::size_of::() { + // 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 Hash for *mut T { + impl Hash for *mut T { fn hash(&self, state: &mut H) { - state.write_usize(*self as usize) + if mem::size_of::() == mem::size_of::() { + // 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); + } } } } diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs index 43ba941f13bfc..8716421b424de 100644 --- a/src/libcore/tests/hash/mod.rs +++ b/src/libcore/tests/hash/mod.rs @@ -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 }