DIP66 - Multiple alias this

IgorStepanov via Digitalmars-d digitalmars-d at puremagic.com
Fri Oct 10 15:10:16 PDT 2014


On Friday, 10 October 2014 at 21:26:49 UTC, Steven Schveighoffer 
wrote:
> On 10/10/14 5:15 PM, IgorStepanov wrote:
>> On Friday, 10 October 2014 at 20:47:45 UTC, Steven 
>> Schveighoffer wrote:
>>> On 10/10/14 1:09 PM, IgorStepanov wrote:
>>>> I've created DIP for my pull request.
>>>> DIP: http://wiki.dlang.org/DIP66
>>>> PR: https://github.com/D-Programming-Language/dmd/pull/3998
>>>>
>>>> Please, comment it.
>>>
>>> This part:
>>>
>>> void test()
>>>    {
>>>        C c;
>>>        int i = c; //Error: c.a.i vs c.b.i
>>>    }
>>>
>>>    static assert(is(C : int)); //Ok, because C is subtype of 
>>> int anyway.
>>>
>>> I think might be wrong. There is a lot of code out there that 
>>> says, e.g.:
>>>
>>> void foo(T)(T t) if(is(T : U))
>>> {
>>>  U u = t;
>>>  ...
>>> }
>>>
>>> Which will now create an error in the wrong place. IMO, the 
>>> 'is' test
>>> should also fail.
>>>
>>> -Steve
>>
>> I thought exactly about this using case.
>>
>> See:
>> You have a struct like this in first place:
>>     struct A
>>     {
>>         int i;
>>         alias i this;
>>     }
>>
>>     struct C
>>     {
>>         A a;
>>         string s;
>>         alias a this;
>>         alias s this;
>>     }
>>
>> And you have a template function in second place:
>> void foo(T)(T t) if(is(T : int))
>> {
>> ...
>> }
>>
>> void foo(T)(T t) if(is(T : string))
>> {
>> ...
>> }
>>
>>
>> And you have the code it third place:
>> C c;
>> foo(c); //Error: what do you mean: foo!(T : string) or foo!(T 
>> : int)
>
> I agree with all this.
>
>> Now, someone (A developer) changed the A definition:
>>
>>     struct A
>>     {
>>         int i;
>>         alias i this;
>>     }
>>
>>     struct B
>>     {
>>         int i;
>>         alias i this;
>>     }
>>
>>     struct C
>>     {
>>         A a;
>>         B b;
>>         string s;
>>         alias a this;
>>         alias b this;
>>         alias s this;
>>     }
>>
>> And now, you code mystically start to works.
>
> Why? It's just as confused as before, no?
>
> The way the DIP reads, the call to foo(c) compiles, but the 
> instantiation fails. This can cause subtle issues when you want 
> to select an instantiation based on what it casts to.
>
> An example:
>
> foo(T)(T t) if(is(T : int))
> {
>    someFuncThatTakesInt(t);
> }
>
> foo(T)(T t) if(!is(T : int) && is(T.shadow : int))
> {
>    someFuncThatTakesInt(t.shadow);
> }
>
> struct A
> {
>    int i;
>    alias i this;
> }
>
> struct B
> {
>    int i;
>    alias i this;
> }
>
> struct C
> {
>    A a;
>    B shadow;
>    alias a this;
>    alias shadow this;
> }
>
> C c;
> foo(c); // should compile, but I think your DIP makes it fail 
> due to ambiguity
>
> -Steve

You can write foo(c.shadow); This isn't hard.
Ok, I understood you, let's listen to what others say


More information about the Digitalmars-d mailing list