Advice on Hashing Confusion

I would like to derive Hash for two struct types. The confusion is that the structs overlap, sharing the same combinations of field types :

#[derive(Hash)]
struct A{
  x: u8, // an x value
  y: u8, // a y value
}
#[derive(Hash)]
struct B{
  r: u8, // an r value
  s: u8, // an s value
}

To my eyes, it seems like these would produce an equivalent hash value based on the fields alone, but the types are not semantically interchangeable (A's fields are in the domain {x, y}, B's fields are in the domain {r,s}, and most obviously, an A is not a B.

If I'm just using the hash for things like indexing in a collection, is it correct to assume that I do not need to care about these "collisions" since the collection is typed with A or B? ( When I look at the std implementation of Hash for str it seems to use as_bytes, which I assume would raise the same possibility of out-of-type collision with a non-str byte slice).

Sorry if this is a beginner question, but I didn't get anywhere searching elsewhere, and I've never needed to implement hashing before.

Indeed, there's no risk of collision between them because a hash map must pick a single specific type as its key. If you make an enum with two cases and use the enum as a key, then the derive for the enum will include the kind in the hash.

3 Likes

Thank you very much.

Generally, Rust APIs, library types, built-in language features, the type system, etc. try very hard to avoid footguns and spooky action at a distance. By default, it's a safe assumption that you don't need to worry about such problems.

(Anyway, hash tables are expected to work correctly even in the presence of collisions, as collisions occur all the time in reality. If a degenerate hasher always returned a constant value, HashMap would still work correctly, albeit the usual expected asymptotic running time of its operations would not be met.)

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.