Bug 11025 – [aa] std.typecons.Tuple needs to define toHash

Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-09-13T13:14:00Z
Last change time
2014-07-04T17:25:21Z
Assigned to
nobody
Creator
hsteoh

Comments

Comment #0 by hsteoh — 2013-09-13T13:14:57Z
Code: ------ import std.typecons; void main() { bool[Tuple!(string,string)] aa; aa[tuple("a", "b")] = true; assert(tuple("a", "b") in aa); // OK due to folding of identical string literals assert(tuple("a".idup, "b".idup) in aa); // NG } ------ Proof that toHash is the problem: ------ import std.typecons, std.stdio; void main() { auto t = tuple("a", "b"); auto u = tuple("a".idup, "b".idup); writeln(typeid(t).getHash(&t)); // prints 18075234133232566449 writeln(typeid(u).getHash(&u)); // prints 5823865589096027868 } ------ It appears that the hash is computed only on the binary representation of the tuple, not on the contents of each field. This causes the AA breakage above.
Comment #1 by dspies — 2014-04-03T15:44:34Z
This seems really serious. It's undocumented, unexpected, and the source of completely untraceable bugs. It applies not just to Tuple, but to the default hash for any user-defined structs. Should this bug be elevated to major or even critical (at least until it's documented on the AA page)?
Comment #2 by hsteoh — 2014-04-03T15:59:12Z
Yes it's a serious bug. Sadly, it's also not a surprising one: the current AA implementation has a lot of issues (and I do mean a LOT), and this is just another hole in the cheesegrater. Basically, the only guaranteed correct behaviour of AA's in their current state is to use string keys or immutable array keys. Anything key type more complicated than that -- all bets are off, you could run into one of numerous AA-related bugs unexpectedly. Having said that, though, AA's with string keys do work great. The workaround for this particular bug is to wrap your key (whether it's Tuple or multiple strings or whatever else) in your own struct, and make sure you define opCmp, opEquals, and toHash with the right signatures for the typeinfo to be set up correctly. And make sure you don't have external mutable references to the key struct after you add it to an AA. Then it should work correctly. (Yes, it's troublesome and tedious, and yes it sucks to have to do that, but given how deeply-rooted some of the AA bugs are, fixes are moving rather slowly, and I wouldn't hold my breath for them to be fixed in the next release. The good news is that D's templating power mostly alleviates this pain once you have the workaround suitably templatized, then you just reuse it everywhere and don't ever worry about manually doing it again.)
Comment #3 by k.hara.pg — 2014-07-04T17:25:21Z
*** This issue has been marked as a duplicate of issue 13045 ***