diff --git a/src/libstd/path.rs b/src/libstd/path.rs index fe12b671235a2..f1422bb501aed 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -103,6 +103,7 @@ use borrow::{Borrow, IntoCow, ToOwned, Cow}; use cmp; use fmt; use fs; +use hash::{Hash, Hasher}; use io; use iter; use mem; @@ -446,7 +447,7 @@ enum State { /// /// Does not occur on Unix. #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Copy, Clone, Eq, Hash, Debug)] +#[derive(Copy, Clone, Eq, Debug)] pub struct PrefixComponent<'a> { /// The prefix as an unparsed `OsStr` slice. raw: &'a OsStr, @@ -490,6 +491,13 @@ impl<'a> cmp::Ord for PrefixComponent<'a> { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Hash for PrefixComponent<'a> { + fn hash(&self, h: &mut H) { + self.parsed.hash(h); + } +} + /// A single component of a path. /// /// See the module documentation for an in-depth explanation of components and @@ -932,7 +940,7 @@ impl<'a> cmp::Ord for Components<'a> { /// path.push("system32"); /// path.set_extension("dll"); /// ``` -#[derive(Clone, Hash)] +#[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct PathBuf { inner: OsString @@ -1171,6 +1179,13 @@ impl cmp::PartialEq for PathBuf { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for PathBuf { + fn hash(&self, h: &mut H) { + self.as_path().hash(h) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Eq for PathBuf {} @@ -1224,7 +1239,6 @@ impl Into for PathBuf { /// let parent_dir = path.parent(); /// ``` /// -#[derive(Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Path { inner: OsStr @@ -1809,6 +1823,15 @@ impl cmp::PartialEq for Path { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Path { + fn hash(&self, h: &mut H) { + for component in self.components() { + component.hash(h); + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl cmp::Eq for Path {} @@ -3035,6 +3058,14 @@ mod tests { #[test] pub fn test_compare() { + use hash::{Hash, Hasher, SipHasher}; + + fn hash(t: T) -> u64 { + let mut s = SipHasher::new_with_keys(0, 0); + t.hash(&mut s); + s.finish() + } + macro_rules! tc( ($path1:expr, $path2:expr, eq: $eq:expr, starts_with: $starts_with:expr, ends_with: $ends_with:expr, @@ -3045,6 +3076,9 @@ mod tests { let eq = path1 == path2; assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}", $path1, $path2, $eq, eq); + assert!($eq == (hash(path1) == hash(path2)), + "{:?} == {:?}, expected {:?}, got {} and {}", + $path1, $path2, $eq, hash(path1), hash(path2)); let starts_with = path1.starts_with(path2); assert!(starts_with == $starts_with,