Closed
Description
I tried this code:
use std::path::PathBuf;
use std::hash::{DefaultHasher, Hasher, Hash};
fn main() {
let x = PathBuf::from("hello/world");
let y = PathBuf::from("helloworld");
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
println!("{}", hasher.finish());
let mut hasher = DefaultHasher::new();
y.hash(&mut hasher);
println!("{}", hasher.finish());
}
I expected to see this happen: Different hashes since these represent different paths.
Instead, this happened: The hashes are equal.
This makes sense for redundant path separators (e.g. //
), but not for all path separators.
I added a test case to the standard library — which fails.
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index 92702b395df..ed945a764c5 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -1566,6 +1566,13 @@ macro_rules! tc (
relative_from: Some("bar")
);
+ tc!("foo/bar", "foobar",
+ eq: false,
+ starts_with: false,
+ ends_with: false,
+ relative_from: None
+ );
+
tc!("foo/bar/baz", "foo/bar",
eq: false,
starts_with: true,
---- path::tests::test_compare stdout ----
thread 'path::tests::test_compare' panicked at library/std/src/path/tests.rs:1569:5:
"foo/bar" == "foobar", expected false, got 4111386826608627770 and 4111386826608627770
The relevant code is probably around
Lines 3112 to 3114 in 6292b2a
Meta
I tested this on stable (1.79.0), nightly (1.81.0), and on master
(6292b2a).
Discovered via astral-sh/ruff#12158