Typeinfo inconsistencies

Maxim Fomin maxim at maxim-fomin.ru
Tue Aug 13 12:48:10 PDT 2013


On Tuesday, 13 August 2013 at 17:42:31 UTC, H. S. Teoh wrote:
> So, I got some free time today and decided to look into issue 
> 6210, and
> found out that the problem was caused by this:
>
> 	char[]        a = "h".dup;
> 	const(char)[] b = "h";
> 	string        c = "h";
>
> 	writeln(typeid(a).getHash(&a)); // prints 104
> 	writeln(typeid(b).getHash(&b)); // prints 703014434222502
> 	writeln(typeid(c).getHash(&c)); // prints 104
>
> This is completely b0rken, because it causes the following code 
> to fail:
>
> 	int[char[]] aa;
> 	aa["h"] = 1;
>
> 	assert(aa.dup == aa);	// fails
>
> The reason for this inconsistency is that char[] and 
> immutable(char)[]
> (aka string) have their getHash functions overridden in 
> druntime's
> src/rt/typeinfo/ti_Ag.d, but there is no such override for
> const(char)[].
>
> I tried adding another subclass for const(char)[]'s typeid that 
> inherits
> the correct version of getHash, but it didn't work because 
> presumably
> this stuff is hardcoded into the compiler somewhere.
>
> So my question is, where in the compiler decides to use the 
> specific
> typeinfos for char[] and immutable(char)[], but not 
> const(char)[]?
>
>
> T

OK

--- a/src/typinf.c
+++ b/src/typinf.c
@@ -790,7 +790,8 @@ int TypeDArray::builtinTypeInfo()
  #if DMDV2
      return !mod && (next->isTypeBasic() != NULL && !next->mod ||
          // strings are so common, make them builtin
-        next->ty == Tchar && next->mod == MODimmutable);
+        next->ty == Tchar && next->mod == MODimmutable ||
+        next->ty == Tchar && next->mod == MODconst);
  #else
      return next->isTypeBasic() != NULL;
  #endif

--- a/src/rt/typeinfo/ti_Ag.d
+++ b/src/rt/typeinfo/ti_Ag.d
@@ -186,3 +186,15 @@ class TypeInfo_Aya : TypeInfo_Aa
      }
  }

+// const(char)[]
+
+class TypeInfo_Axa : TypeInfo_Aa
+{
+    override string toString() const { return "const(char)[]"; }
+
+    override @property inout(TypeInfo) next() inout
+    {
+        return cast(inout)typeid(const(char));
+    }
+}
+

and this program runs fine and prints 104 for three cases

import std.stdio;

void main()
{
    int[char[]] aa;
    aa["h"] = 1;
    assert(aa.dup == aa);   // fails, now ok


    char[]        a = "h".dup;
    const(char)[] b = "h";
    string        c = "h";
    writeln(typeid(a).getHash(&a)); // prints 104
    writeln(typeid(b).getHash(&b)); // prints 703014434222502, now 
104
    writeln(typeid(c).getHash(&c)); // prints 104
}


More information about the Digitalmars-d mailing list