On Monday, February 27, 2012 17:28:17 H. S. Teoh wrote: > On Mon, Feb 27, 2012 at 02:41:27PM -0800, H. S. Teoh wrote: > > I'm investigating issue 7512, and narrowed down the problem to a bug > > somewhere in the code that handles AA literals. > > [...] > > OK, I've found the cause of the problem. Suppose you have an int array: > > const int[] key = [1,2,3,4]; > > and you create an AA out of it with an AA literal: > > int[int[]] map1 = [ key: 1234 ]; > > then internally, map1's key TypeInfo points to const(int)[]. > > However, if you do this: > > int[int[]] map2; > map2[key] = 1234; > > then internally, map2's key TypeInfo points to int[]. (Non-const!) > > This difference means that the hash value of 'key' in map1 is > *different* from the hash value of 'key' in map2. But if you now write > this: > > map1[key] = 1234; > > for some reason, the hash value of 'key' is *still* computed using > int[], even though map1's key TypeInfo points to const(int)[]. So the > wrong hash value is computed, and the entry is not found. This means > that you will never find anything in map1 using map1.get or map1[...]. > But foreach works 'cos no hash values are involved. > > The above line will actually create a duplicate entry in the hash table, > because 'key' is hashed to a different value than the one set by the AA > literal. > > So the question is: > > 1) Why does map2's internal TypeInfo get set to int[] instead of > const(int)[]? > > 2) Why does map1[key] use int[]'s version of getHash() even though > map1's TypeInfo actually points to const(int)[]? > > > This completely breaks AA literals for wstring keys, dstring keys, and > in fact *any* array-typed key except for string (which for some blessed > reason doesn't suffer from this breakage). > > Question: is this a compiler bug, or a druntime bug?
The keys to AA's are supposed to be _immutable_. Really, this should be enforced by the compiler (and it is on some level, but not to the point that code like int[int[]] is illegal like it should be). The fact that the implementation is using const internally just makes it that much worse. - Jonathan M Davis