Thread overview
A few bugs connected to structs
Jan 11, 2012
Benjamin Thaut
Jan 11, 2012
Timon Gehr
Jan 12, 2012
Benjamin Thaut
Jan 12, 2012
Benjamin Thaut
Jan 12, 2012
Benjamin Thaut
Jan 12, 2012
kenji hara
Jan 12, 2012
Benjamin Thaut
January 11, 2012
1. It's currently not possible to overload opAssign for structs with a template because opAssign(T)(T rh) if(is(T == typeof(this)))

is not allowed (stated in the documentation). And templates can not overload non template functions (already a known bug).

2. It's not possible to use auto ref with opAssign because opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed (partly the same issue as 1).

Why is this not allowed? (The documentation does not state any reason)

3. Calling a method that is overloaded with shared / const / immutable from within a function has to be done with this.method()
otherwise the compiler complains about ambugiosity. Is method() not the same as this.method() ??

-- 
Kind Regards
Benjamin Thaut
January 11, 2012
On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
> 1. It's currently not possible to overload opAssign for structs with a
> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>
> is not allowed (stated in the documentation). And templates can not
> overload non template functions (already a known bug).
>
> 2. It's not possible to use auto ref with opAssign because
> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
> (partly the same issue as 1).
>
> Why is this not allowed? (The documentation does not state any reason)

There is no reason, and DMD accepts it. Maybe file a bug against the documentation?

struct S{
    auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
}

void main(){
    S a, b;
    a=b;
}

>
> 3. Calling a method that is overloaded with shared / const / immutable
> from within a function has to be done with this.method()
> otherwise the compiler complains about ambugiosity. Is method() not the
> same as this.method() ??
>

Yes it is. Has this been filed already?
January 12, 2012
Am 11.01.2012 20:05, schrieb Timon Gehr:
> On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
>> 1. It's currently not possible to overload opAssign for structs with a
>> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>>
>> is not allowed (stated in the documentation). And templates can not
>> overload non template functions (already a known bug).
>>
>> 2. It's not possible to use auto ref with opAssign because
>> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
>> (partly the same issue as 1).
>>
>> Why is this not allowed? (The documentation does not state any reason)
>
> There is no reason, and DMD accepts it. Maybe file a bug against the
> documentation?
>
> struct S{
> auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
> }
>
> void main(){
> S a, b;
> a=b;
> }
>
>>
>> 3. Calling a method that is overloaded with shared / const / immutable
>> from within a function has to be done with this.method()
>> otherwise the compiler complains about ambugiosity. Is method() not the
>> same as this.method() ??
>>
>
> Yes it is. Has this been filed already?

The bugs are not filed yet as I wanted to make sure that they are actually bugs. I have repro cases for both of them, I just need to shrink them down. As soon as I have small repro cases I'm going to file them.

-- 
Kind Regards
Benjamin Thaut
January 12, 2012
Am 11.01.2012 20:05, schrieb Timon Gehr:
> On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
>> 1. It's currently not possible to overload opAssign for structs with a
>> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>>
>> is not allowed (stated in the documentation). And templates can not
>> overload non template functions (already a known bug).
>>
>> 2. It's not possible to use auto ref with opAssign because
>> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
>> (partly the same issue as 1).
>>
>> Why is this not allowed? (The documentation does not state any reason)
>
> There is no reason, and DMD accepts it. Maybe file a bug against the
> documentation?
>
> struct S{
> auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
> }
>
> void main(){
> S a, b;
> a=b;
> }
>
>>
>> 3. Calling a method that is overloaded with shared / const / immutable
>> from within a function has to be done with this.method()
>> otherwise the compiler complains about ambugiosity. Is method() not the
>> same as this.method() ??
>>
>
> Yes it is. Has this been filed already?

Bug ticket for issue 3: http://d.puremagic.com/issues/show_bug.cgi?id=7276

-- 
Kind Regards
Benjamin Thaut
January 12, 2012
Am 11.01.2012 20:05, schrieb Timon Gehr:
> On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
>> 1. It's currently not possible to overload opAssign for structs with a
>> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>>
>> is not allowed (stated in the documentation). And templates can not
>> overload non template functions (already a known bug).
>>
>> 2. It's not possible to use auto ref with opAssign because
>> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
>> (partly the same issue as 1).
>>
>> Why is this not allowed? (The documentation does not state any reason)
>
> There is no reason, and DMD accepts it. Maybe file a bug against the
> documentation?
>
> struct S{
> auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
> }
>
> void main(){
> S a, b;
> a=b;
> }
>
>>
>> 3. Calling a method that is overloaded with shared / const / immutable
>> from within a function has to be done with this.method()
>> otherwise the compiler complains about ambugiosity. Is method() not the
>> same as this.method() ??
>>
>
> Yes it is. Has this been filed already?

I have a repro case for issue 1+2. It seems to be connected to the bostplit constructor. Does the postblit constructor infer with opAssign overloading?

struct Array(T){
  T[] data;

  alias typeof(this) this_t;

  this(this)
  {
    data = data.dup;
  }

  this_t opAssign(U)(auto ref U rh) if(is(U == this_t))
  {
    data = rh.data;
    return rh;
  }

  auto opAssign(U)(U rh) if(is(U == T[]))
  {
    data = rh;
    return rh;
  }
}

int main(string[] argv)
{
   Array!int bla;
   bla = [1,2,3];
   return 0;
}

main.d(15): Error: function main.Array!(int).Array.opAssign conflicts with template main.Array!(int).Array.opAssign(U) if (is(U == this_t)) at main.d(25)
main.d(40): Error: template instance main.Array!(int) error instantiating

-- 
Kind Regards
Benjamin Thaut
January 12, 2012
The definition of postblit generates an non-templated built-in
opAssign implicitly.
And it conflicts with your templated opAssign.

It is already filed in bugzilla.

Issue 4424 - Copy constructor and templated opAssign cannot coexist http://d.puremagic.com/issues/show_bug.cgi?id=4424

Kenji Hara

2012/1/12 Benjamin Thaut <code@benjamin-thaut.de>:
> Am 11.01.2012 20:05, schrieb Timon Gehr:
>>
>> On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
>>
>>> 1. It's currently not possible to overload opAssign for structs with a
>>> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>>>
>>> is not allowed (stated in the documentation). And templates can not
>>> overload non template functions (already a known bug).
>>>
>>> 2. It's not possible to use auto ref with opAssign because
>>> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
>>> (partly the same issue as 1).
>>>
>>> Why is this not allowed? (The documentation does not state any reason)
>>
>>
>> There is no reason, and DMD accepts it. Maybe file a bug against the documentation?
>>
>> struct S{
>> auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
>> }
>>
>> void main(){
>> S a, b;
>> a=b;
>> }
>>
>>>
>>> 3. Calling a method that is overloaded with shared / const / immutable
>>> from within a function has to be done with this.method()
>>> otherwise the compiler complains about ambugiosity. Is method() not the
>>> same as this.method() ??
>>>
>>
>> Yes it is. Has this been filed already?
>
>
> I have a repro case for issue 1+2. It seems to be connected to the bostplit constructor. Does the postblit constructor infer with opAssign overloading?
>
> struct Array(T){
>  T[] data;
>
>  alias typeof(this) this_t;
>
>  this(this)
>  {
>    data = data.dup;
>  }
>
>  this_t opAssign(U)(auto ref U rh) if(is(U == this_t))
>  {
>    data = rh.data;
>    return rh;
>  }
>
>  auto opAssign(U)(U rh) if(is(U == T[]))
>  {
>    data = rh;
>    return rh;
>  }
> }
>
> int main(string[] argv)
> {
>   Array!int bla;
>   bla = [1,2,3];
>   return 0;
> }
>
> main.d(15): Error: function main.Array!(int).Array.opAssign conflicts with
> template main.Array!(int).Array.opAssign(U) if (is(U == this_t)) at
> main.d(25)
> main.d(40): Error: template instance main.Array!(int) error instantiating
>
>
> --
> Kind Regards
> Benjamin Thaut
January 12, 2012
Am 12.01.2012 08:15, schrieb kenji hara:
> The definition of postblit generates an non-templated built-in
> opAssign implicitly.
> And it conflicts with your templated opAssign.
>
> It is already filed in bugzilla.
>
> Issue 4424 - Copy constructor and templated opAssign cannot coexist
> http://d.puremagic.com/issues/show_bug.cgi?id=4424
>
> Kenji Hara
>
> 2012/1/12 Benjamin Thaut<code@benjamin-thaut.de>:
>> Am 11.01.2012 20:05, schrieb Timon Gehr:
>>>
>>> On 01/11/2012 05:58 PM, Benjamin Thaut wrote:
>>>
>>>> 1. It's currently not possible to overload opAssign for structs with a
>>>> template because opAssign(T)(T rh) if(is(T == typeof(this)))
>>>>
>>>> is not allowed (stated in the documentation). And templates can not
>>>> overload non template functions (already a known bug).
>>>>
>>>> 2. It's not possible to use auto ref with opAssign because
>>>> opAssign(T)(auto ref T rh) if(is(T == typeof(this))) is not allowed
>>>> (partly the same issue as 1).
>>>>
>>>> Why is this not allowed? (The documentation does not state any reason)
>>>
>>>
>>> There is no reason, and DMD accepts it. Maybe file a bug against the
>>> documentation?
>>>
>>> struct S{
>>> auto opAssign(T)(auto ref T rhs) if(is(T==typeof(this))){return rhs;}
>>> }
>>>
>>> void main(){
>>> S a, b;
>>> a=b;
>>> }
>>>
>>>>
>>>> 3. Calling a method that is overloaded with shared / const / immutable
>>>> from within a function has to be done with this.method()
>>>> otherwise the compiler complains about ambugiosity. Is method() not the
>>>> same as this.method() ??
>>>>
>>>
>>> Yes it is. Has this been filed already?
>>
>>
>> I have a repro case for issue 1+2. It seems to be connected to the bostplit
>> constructor. Does the postblit constructor infer with opAssign overloading?
>>
>> struct Array(T){
>>   T[] data;
>>
>>   alias typeof(this) this_t;
>>
>>   this(this)
>>   {
>>     data = data.dup;
>>   }
>>
>>   this_t opAssign(U)(auto ref U rh) if(is(U == this_t))
>>   {
>>     data = rh.data;
>>     return rh;
>>   }
>>
>>   auto opAssign(U)(U rh) if(is(U == T[]))
>>   {
>>     data = rh;
>>     return rh;
>>   }
>> }
>>
>> int main(string[] argv)
>> {
>>    Array!int bla;
>>    bla = [1,2,3];
>>    return 0;
>> }
>>
>> main.d(15): Error: function main.Array!(int).Array.opAssign conflicts with
>> template main.Array!(int).Array.opAssign(U) if (is(U == this_t)) at
>> main.d(25)
>> main.d(40): Error: template instance main.Array!(int) error instantiating
>>
>>
>> --
>> Kind Regards
>> Benjamin Thaut

Thanks for the info. It's nice that there is already a pull request to fix this.

-- 
Kind Regards
Benjamin Thaut