Compiler fails to match array literal to byte[] in templated functions (Was: Re: More putrid beef soup (Was: Re: Implicit string lit conversion) to wstring/dstring)

Timon Gehr timon.gehr at gmx.ch
Mon Mar 19 02:46:20 PDT 2012


On 03/19/2012 04:40 AM, H. S. Teoh wrote:
> OK, perhaps the previous subject line of the previous post deterred
> people from actually reading the contents. :-(
>
> Basically, I'm trying to address Andrei's request that this should work
> with my AA implementation:
>
> 	int[dstring] aa;
> 	aa["abc"] = 1;	// "abc" implicitly deduced as dstring
>
> Currently, for maximum usability, the code allows any type to be
> supplied for the key, as long as it can be implicitly converted to the
> AA's key type. This is implemented as:
>
> 	opIndexAssign(K)(Value v, K key) if (implicitConvertible!K) {}
>
> However, this causes a problem with dstring and wstring, because a
> literal like "abc" defaults to string rather than dstring or wstring, so
> when the compiler tries to find a match for opIndexAssign, it sees that
> string can't implicitly convert to dstring, so it produces an error.
>
> This doesn't happen if opIndexAssign was simply:
>
> 	opIndexAssign(Value v, Key key) {}
>
> where Key==dstring, because then the compiler implicitly deduces "abc"
> as a dstring.
>
> In order to fix this, one fix is:
>
> 	// Key==dstring
> 	opIndexAssign()(Value v, Key key) { __opIndexAssignImpl(v,key); }
> 	opIndexAssign(K)(Value v, K key)
> 		if (implicitConvertible!K&&  !is(K==string))
> 	{
> 		__opIndexAssignImpl(v,key);
> 	}
>
> How this works is, when the compiler sees "abc", it first tries to match
> opIndexAssign(K=string)(Value,K), defaulting "abc" to string, but the
> signature constraint declines, so the compiler tries
> opIndexAssign()(Value v, dstring key), which matches with "abc" as
> dstring.
>
> This works for string, wstring, and dstring.
>
> However, the compiler seems to handle numerical literals like [1,2,3]
> differently. For example:
>
> 	void func(byte[] b) {}
> 	func([1,2,3]);		// OK
>
> However:
>
> 	void func()(byte[] b) {}
> 	func([1,2,3]);		// Does not match template
>
> Because of this, it's basically impossible to make literals like [1,2,3]
> work with AA's with key type byte[], short[], etc., because [1,2,3] will
> never match byte[] in a templated function, and int[] cannot be
> implicitly converted to byte[]. So it is impossible to replicate the
> implicit conversion in code like:
>
> 	byte[] b;
> 	b = [1,2,3];
>
> without compiler changes. :-(
>
>
> --T

This is a bug I have reported some time ago.

Vote here: http://d.puremagic.com/issues/show_bug.cgi?id=7366





More information about the Digitalmars-d mailing list