Need help locating AA bug
H. S. Teoh
hsteoh at quickfur.ath.cx
Mon Feb 27 17:28:17 PST 2012
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:
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
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
So the question is:
1) Why does map2's internal TypeInfo get set to int instead of
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?
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.
More information about the Digitalmars-d