Re: 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)

2012-03-19 Thread Timon Gehr

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





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)

2012-03-18 Thread H. S. Teoh
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


Re: 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)

2012-03-18 Thread James Miller
On 19 March 2012 16:40, H. S. Teoh hst...@quickfur.ath.cx 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 sounds like a major bug. At compile time, the compiler should
have more than enough information to do the implicit conversion for
templates.

I haven't looked much at the compiler code, but I assume that there is
a semantic pass that does the implicit conversions? Could that be
used/copied to where templates get instantiated?

--
James Miller


More putrid beef soup (Was: Re: Implicit string lit conversion to wstring/dstring)

2012-03-17 Thread H. S. Teoh
On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:
[...]
 Aha! This is one of those cases in which built-in magic smells of
 putrid beef soup.
[...]

It gets worse than we first thought:

void f1(dstring x) { dstring y = x; }

void f2()(dstring x) { dstring y = x; }
void f2(U)(U x) if (!is(U==string)) { dstring y = x; }

void f3(byte[] x) { byte[] y = x; }

void f4()(byte[] x) { byte[] y = x; }
void f4(U)(U x) if (!is(U==int[])) { byte[] y = x; }

void main() {
f1(abc);  // OK: abc deduced as dstring

f2(abc);  // OK: abc defaults to string, but f2(U)(U)
// declines U==string, so f2()(dstring) is
// chosen, and abc is deduced as dstring

f3([1,2,3]);// OK: [1,2,3] deduced as byte[]

f4([1,2,3]);// Error: template test2.f4() does not match 
any function template declaration
// Error: template test2.f4() cannot deduce 
template function from argument types !()(int[])
}

WAT?? So abc will match f()(dstring x), but [1,2,3] doesn't match
f()(byte[] b)?

Upon further investigation:

void f5(dstring s) {}
void f6()(dstring s) {}
void f7(byte[] s) {}
void f8()(byte[] s) {}
void main() {
f5(abc);  // OK
f6(abc);  // OK (!)
f7([1,2,3]);// OK

f8([1,2,3]);// cannot deduce template function from 
argument types !()(int[])
}

WAT?


T

-- 
You know, maybe we don't *need* enemies. Yeah, best friends are about all I 
can take. -- Calvin  Hobbes


Implicit string lit conversion to wstring/dstring

2012-03-14 Thread H. S. Teoh
Code:
import std.stdio;
version(explicit) {
void func(dstring s) {
dstring t = s;
writeln(t);
}
} else {
void func(S)(S s) {
dstring t = s;  // line 10
writeln(t);
}
}
void main() {
func(abc);
}

If version=explicit is set, the program compiles fine. But if not, then
the compiler complains:

test.d:10: Error: cannot implicitly convert expression (s) of type 
string to immutable(dchar)[]

What do I need to do to make the template version of func trigger
implicit conversion of the string lit to dstring? What I'm trying to do
is to templatize dstring as well, but still benefit from the
string-dstring conversion when instantiated with dstring.

(Ditto with implicit conversion to wstring.)


T

-- 
He who laughs last thinks slowest.


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Alex Rønne Petersen

On 14-03-2012 19:00, H. S. Teoh wrote:

Code:
import std.stdio;
version(explicit) {
void func(dstring s) {
dstring t = s;
writeln(t);
}
} else {
void func(S)(S s) {
dstring t = s;  // line 10
writeln(t);
}
}
void main() {
func(abc);
}

If version=explicit is set, the program compiles fine. But if not, then
the compiler complains:

test.d:10: Error: cannot implicitly convert expression (s) of type 
string to immutable(dchar)[]

What do I need to do to make the template version of func trigger
implicit conversion of the string lit to dstring? What I'm trying to do
is to templatize dstring as well, but still benefit from the
string-dstring conversion when instantiated with dstring.

(Ditto with implicit conversion to wstring.)


T



I doubt that such an implicit conversion even exists. You have to prefix 
the string appropriately, e.g.:


string s = foo;
wstring w = wbar;
dstring d = dbaz;

--
- Alex


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Alex Rønne Petersen

On 14-03-2012 19:00, Alex Rønne Petersen wrote:

On 14-03-2012 19:00, H. S. Teoh wrote:

Code:
import std.stdio;
version(explicit) {
void func(dstring s) {
dstring t = s;
writeln(t);
}
} else {
void func(S)(S s) {
dstring t = s; // line 10
writeln(t);
}
}
void main() {
func(abc);
}

If version=explicit is set, the program compiles fine. But if not, then
the compiler complains:

test.d:10: Error: cannot implicitly convert expression (s) of type
string to immutable(dchar)[]

What do I need to do to make the template version of func trigger
implicit conversion of the string lit to dstring? What I'm trying to do
is to templatize dstring as well, but still benefit from the
string-dstring conversion when instantiated with dstring.

(Ditto with implicit conversion to wstring.)


T



I doubt that such an implicit conversion even exists. You have to prefix
the string appropriately, e.g.:

string s = foo;
wstring w = wbar;
dstring d = dbaz;



Sorry, I lied. Like this:

string s = fooc; (the c is optional)
wstring w = barw;
dstring d = bazd;

See: http://dlang.org/lex.html

--
- Alex


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread H. S. Teoh
On Wed, Mar 14, 2012 at 07:00:35PM +0100, Alex Rønne Petersen wrote:
 On 14-03-2012 19:00, H. S. Teoh wrote:
 Code:
  import std.stdio;
  version(explicit) {
  void func(dstring s) {
  dstring t = s;
  writeln(t);
  }
  } else {
  void func(S)(S s) {
  dstring t = s;  // line 10
  writeln(t);
  }
  }
  void main() {
  func(abc);
  }
 
 If version=explicit is set, the program compiles fine. But if not, then
 the compiler complains:
 
  test.d:10: Error: cannot implicitly convert expression (s) of type 
  string to immutable(dchar)[]
 
 What do I need to do to make the template version of func trigger
 implicit conversion of the string lit to dstring? What I'm trying to do
 is to templatize dstring as well, but still benefit from the
 string-dstring conversion when instantiated with dstring.
 
 (Ditto with implicit conversion to wstring.)
 
 
 T
 
 
 I doubt that such an implicit conversion even exists. You have to
 prefix the string appropriately, e.g.:

OK, maybe implicit conversion is the wrong word. The compiler is
obviously interpreting func(abc) as func(abcd) when we declare
func(dstring). But when we declare func(S)(S), the compiler deduces
abc as string and sets S=string.

What I want is to force the compiler to deduce S=dstring when I declare
func(S)(S) and call it as func(abc).


T

-- 
Дерево держится корнями, а человек - друзьями.


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Alex Rønne Petersen

On 14-03-2012 19:16, H. S. Teoh wrote:

On Wed, Mar 14, 2012 at 07:00:35PM +0100, Alex Rønne Petersen wrote:

On 14-03-2012 19:00, H. S. Teoh wrote:

Code:
import std.stdio;
version(explicit) {
void func(dstring s) {
dstring t = s;
writeln(t);
}
} else {
void func(S)(S s) {
dstring t = s;  // line 10
writeln(t);
}
}
void main() {
func(abc);
}

If version=explicit is set, the program compiles fine. But if not, then
the compiler complains:

test.d:10: Error: cannot implicitly convert expression (s) of type 
string to immutable(dchar)[]

What do I need to do to make the template version of func trigger
implicit conversion of the string lit to dstring? What I'm trying to do
is to templatize dstring as well, but still benefit from the
string-dstring conversion when instantiated with dstring.

(Ditto with implicit conversion to wstring.)


T



I doubt that such an implicit conversion even exists. You have to
prefix the string appropriately, e.g.:


OK, maybe implicit conversion is the wrong word. The compiler is
obviously interpreting func(abc) as func(abcd) when we declare
func(dstring). But when we declare func(S)(S), the compiler deduces
abc as string and sets S=string.

What I want is to force the compiler to deduce S=dstring when I declare
func(S)(S) and call it as func(abc).


T



But then... why not just make it take a dstring? Maybe I'm not following 
your intent here...


Anyway, what Phobos functions tend to do is to set S = string by default 
and otherwise force people to either pass the string type *or* use the 
string suffices.


--
- Alex


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Dmitry Olshansky

On 14.03.2012 22:00, H. S. Teoh wrote:

Code:
import std.stdio;
version(explicit) {
void func(dstring s) {
dstring t = s;
writeln(t);
}
} else {
void func(S)(S s) {
dstring t = s;  // line 10
writeln(t);
}
}
void main() {
func(abc);
}

If version=explicit is set, the program compiles fine. But if not, then
the compiler complains:

test.d:10: Error: cannot implicitly convert expression (s) of type 
string to immutable(dchar)[]

What do I need to do to make the template version of func trigger
implicit conversion of the string lit to dstring? What I'm trying to do
is to templatize dstring as well, but still benefit from the
string-dstring conversion when instantiated with dstring.

(Ditto with implicit conversion to wstring.)


T


How about this (untested)?

void func()(dstring s) {
dstring t = s;
//...   funcImpl(t);
}
void func(S)(S s) {
dstring t = to!dstring(s);
//...   funcImpl(t);
}

--
Dmitry Olshansky


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Nick Sabalausky
Alex Rønne Petersen xtzgzo...@gmail.com wrote in message 
news:jjqn9f$1iht$1...@digitalmars.com...

 But then... why not just make it take a dstring? Maybe I'm not following 
 your intent here...


Probably because then this becomes an error:

string s = abc;
func(s);

It's an interesting problem. I'm not aware of a solution. I suppose you'd 
just have to make it take only dstring and then expect string/wstring vars 
to be handled by the caller like func(to!dstring(s))




Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Nick Sabalausky
Dmitry Olshansky dmitry.o...@gmail.com wrote in message 
news:jjqnnj$1j86$1...@digitalmars.com...

 How about this (untested)?

 void func()(dstring s) {
 dstring t = s;
 //... funcImpl(t);
 }
 void func(S)(S s) {
 dstring t = to!dstring(s);
 //... funcImpl(t);
 }


That fails to compile when passed a dstring because it matches both 
functions. Adding an if(!is(S==dstring)) constraint to the second makes it 
compile, but then func(abc) just calls the second one instead of the 
first.




Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Steven Schveighoffer
On Wed, 14 Mar 2012 14:16:11 -0400, H. S. Teoh hst...@quickfur.ath.cx  
wrote:



What I want is to force the compiler to deduce S=dstring when I declare
func(S)(S) and call it as func(abc).


http://d.puremagic.com/issues/show_bug.cgi?id=4998

Please vote or contribute your thoughts.

-Steve


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread H. S. Teoh
On Wed, Mar 14, 2012 at 02:44:40PM -0400, Steven Schveighoffer wrote:
 On Wed, 14 Mar 2012 14:16:11 -0400, H. S. Teoh
 hst...@quickfur.ath.cx wrote:
 
 What I want is to force the compiler to deduce S=dstring when I
 declare func(S)(S) and call it as func(abc).
 
 http://d.puremagic.com/issues/show_bug.cgi?id=4998
 
 Please vote or contribute your thoughts.
[...]

Ahhh, thanks for pointing this out. That is exactly the problem I'm
struggling with.

I guess the motivation of my original question wasn't clear. I should
say that I ran into this problem in the context of my AA implementation.
I've successfully implemented Andrei's suggestion: int[wstring] will now
accept wchar[], const(wchar)[], in addition to wstring in .get,
.opIndex, etc.. It will implicitly call wchar[].idup when it needs to
create a new hash entry. (Ditto with dstring, and with any immutable
array key type.)

To implement this change, opIndexAssign now looks like this:

struct AssociativeArray(Key,Value) {
...
void opIndexAssign(K)(in Value v, in K key)
if (isCompatWithKey!K)
{
...
}
}

The template isCompatWithKey basically checks if K can be implicitly
converted to Key, or has an .idup method that returns something that can
be implicitly converted to Key.

However, this change broke this code:

AssociativeArray!(wstring,int) aa;
aa[abc] = 123;// error: compiler deduces K as string,
// so isCompatWithKey!K fails: string
// can't implicitly convert to wstring

Whereas before, when opIndexAssign looked like this:

void opIndexAssign(in Value v, in Key key)
{
...
}

everything worked, because the compiler deduces the type of abc as
wstring since Key==wstring.

Now you have to write:

aa[abcw] = 123;

which isn't the end of the world, I suppose, but it's not very nice, and
also breaks existing code that depended on the compiler automatically
deducing that typeof(abc)==wstring.


T

-- 
There are three kinds of people in the world: those who can count, and those 
who can't.


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Andrei Alexandrescu

On 3/14/12 2:01 PM, H. S. Teoh wrote:

However, this change broke this code:

AssociativeArray!(wstring,int) aa;
aa[abc] = 123;  // error: compiler deduces K as string,
// so isCompatWithKey!K fails: string
// can't implicitly convert to wstring

Whereas before, when opIndexAssign looked like this:

void opIndexAssign(in Value v, in Key key)
{
...
}

everything worked, because the compiler deduces the type of abc as
wstring since Key==wstring.


Aha! This is one of those cases in which built-in magic smells of putrid 
beef soup.


I think it's possible to still make this work by beefing up the template 
constraints such that the working signature is selected for strings.



Andrei



Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread H. S. Teoh
On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:
 On 3/14/12 2:01 PM, H. S. Teoh wrote:
 However, this change broke this code:
 
  AssociativeArray!(wstring,int) aa;
  aa[abc] = 123;// error: compiler deduces K as string,
  // so isCompatWithKey!K fails: string
  // can't implicitly convert to wstring
 
 Whereas before, when opIndexAssign looked like this:
 
  void opIndexAssign(in Value v, in Key key)
  {
  ...
  }
 
 everything worked, because the compiler deduces the type of abc as
 wstring since Key==wstring.
 
 Aha! This is one of those cases in which built-in magic smells of
 putrid beef soup.

+1.


 I think it's possible to still make this work by beefing up the
 template constraints such that the working signature is selected for
 strings.
[...]

I tried the following, but it still doesn't work properly:

void opIndexAssign()(in Value v, in Key key)
{
__opIndexAssignImpl(v, key);
}

void opIndexAssign(K)(in Value v, in K key)
if (!is(K==Key)  isCompatWithKey!K)
{
__opIndexAssignImpl(v, key);
}

This causes this case to fail:

AssociativeArray!(wstring,int) aa;
wchar[] key = abcw.dup;
aa[key] = 123;  // Error: template 
newAA.AA!(immutable(wchar)[],int).AssociativeArray.opIndexAssign() cannot 
deduce template function from argument types !()(int,wchar[])

I don't understand what's happening here.  The condition !is(K==Key)
is necessary because otherwise the compiler complains that more than one
template matches the given call, but for some weird reason both
templates vanish from consideration when the condition is put in.


T

-- 
It is the quality rather than the quantity that matters. -- Lucius Annaeus 
Seneca


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread H. S. Teoh
On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:
 On 3/14/12 2:01 PM, H. S. Teoh wrote:
 However, this change broke this code:
 
  AssociativeArray!(wstring,int) aa;
  aa[abc] = 123;// error: compiler deduces K as string,
  // so isCompatWithKey!K fails: string
  // can't implicitly convert to wstring
 
 Whereas before, when opIndexAssign looked like this:
 
  void opIndexAssign(in Value v, in Key key)
  {
  ...
  }
 
 everything worked, because the compiler deduces the type of abc as
 wstring since Key==wstring.
 
 Aha! This is one of those cases in which built-in magic smells of
 putrid beef soup.
 
 I think it's possible to still make this work by beefing up the
 template constraints such that the working signature is selected for
 strings.
[...]

Also, IMHO, this needs to work for array literals in general, not just
strings. For example, this should work:

int[ubyte[]] aa;
aa[[1,2,3]] = 123;

The [1,2,3] should be deduced as ubyte[] instead of int[].


T

-- 
Ignorance is bliss... but only until you suffer the consequences!


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Andrei Alexandrescu

On 3/14/12 2:34 PM, H. S. Teoh wrote:

I tried the following, but it still doesn't work properly:

void opIndexAssign()(in Value v, in Key key)
{
__opIndexAssignImpl(v, key);
}

void opIndexAssign(K)(in Value v, in K key)
if (!is(K==Key)  isCompatWithKey!K)
{
__opIndexAssignImpl(v, key);
}


Try special casing for the exact types (string, char[] etc), get that 
working, and then generalize from there.


Andrei


Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Timon Gehr

On 03/14/2012 08:34 PM, H. S. Teoh wrote:

On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:

On 3/14/12 2:01 PM, H. S. Teoh wrote:

However, this change broke this code:

AssociativeArray!(wstring,int) aa;
aa[abc] = 123;  // error: compiler deduces K as string,
// so isCompatWithKey!K fails: string
// can't implicitly convert to wstring

Whereas before, when opIndexAssign looked like this:

void opIndexAssign(in Value v, in Key key)
{
...
}

everything worked, because the compiler deduces the type of abc as
wstring since Key==wstring.


Aha! This is one of those cases in which built-in magic smells of
putrid beef soup.


+1.



I think it's possible to still make this work by beefing up the
template constraints such that the working signature is selected for
strings.

[...]

I tried the following, but it still doesn't work properly:

void opIndexAssign()(in Value v, in Key key)
{
__opIndexAssignImpl(v, key);
}

void opIndexAssign(K)(in Value v, in K key)
if (!is(K==Key)  isCompatWithKey!K)
{
__opIndexAssignImpl(v, key);
}

This causes this case to fail:

AssociativeArray!(wstring,int) aa;
wchar[] key = abcw.dup;
aa[key] = 123;  // Error: template 
newAA.AA!(immutable(wchar)[],int).AssociativeArray.opIndexAssign() cannot 
deduce template function from argument types !()(int,wchar[])

I don't understand what's happening here.  The condition !is(K==Key)
is necessary because otherwise the compiler complains that more than one
template matches the given call, but for some weird reason both
templates vanish from consideration when the condition is put in.


T



Use this for now:
void opIndexAssign(K)(in int v, scope K key)
if (!is(K==Key)  isCompatWithKey!K)
{...}

'in K key'/const(K) key will only IFTI-match a const type. I don't think 
that is sensible at all, you may want to file a bug report.





Re: Implicit string lit conversion to wstring/dstring

2012-03-14 Thread Timon Gehr

On 03/14/2012 09:18 PM, Timon Gehr wrote:


Use this for now:
void opIndexAssign(K)(in int v, scope K key)
if (!is(K==Key)  isCompatWithKey!K)
{...}



oops.

I meant:
void opIndexAssign(K)(in Value v, scope K key)
if (!is(K==Key)  isCompatWithKey!K)
{...}


'in K key'/const(K) key will only IFTI-match a const type. I don't think
that is sensible at all, you may want to file a bug report.