Thread overview
pure opApply
Mar 31, 2016
Q. Schroll
Mar 31, 2016
Q. Schroll
March 31, 2016
Simple as that, shouldn't this work?

struct X
{
    int opApply(int delegate(string) dg)
    {
        return dg("impure");
    }

    int opApply(int delegate(string) pure dg) pure
    {
        return dg("pure");
    }
}

void main()
{
    X x;
    string result;

    x.opApply(
        (string s)
        {
            result = s;
            return 0;
        }
    );
    writeln(result); // does compile and prints "pure".

    x.opApply(
        (string s)
        {
            result = s;
            write("");
            return 0;
        }
    );
    writeln(result); // does compile and prints "impure".

    /+ (1)
    foreach (string s; x)
    {
        result = s;
    }
    writeln(result); // does not compile: x.opApply matches more than one declaration
    +/
    /+ (2)
    foreach (string s; x)
    {
        result = s;
        write("");
    }
    writeln(result); // does not compile: x.opApply matches more than one declaration
    +/
}

Can someone explain me, why the compiler cannot resolve the right opApply? From what I know, it generates a delegate with inferred pure attribute and looks for the best match of opApply. Why does the manual rewrite work? If I've done the rewrite improperly, please tell me.
March 31, 2016
On 3/31/16 6:23 AM, Q. Schroll wrote:
> Simple as that, shouldn't this work?
>
> struct X
> {
>      int opApply(int delegate(string) dg)
>      {
>          return dg("impure");
>      }
>
>      int opApply(int delegate(string) pure dg) pure
>      {
>          return dg("pure");
>      }
> }
>
> void main()
> {
>      X x;
>      string result;
>
>      x.opApply(
>          (string s)
>          {
>              result = s;
>              return 0;
>          }
>      );
>      writeln(result); // does compile and prints "pure".
>
>      x.opApply(
>          (string s)
>          {
>              result = s;
>              write("");
>              return 0;
>          }
>      );
>      writeln(result); // does compile and prints "impure".
>
>      /+ (1)
>      foreach (string s; x)
>      {
>          result = s;
>      }
>      writeln(result); // does not compile: x.opApply matches more than
> one declaration
>      +/
>      /+ (2)
>      foreach (string s; x)
>      {
>          result = s;
>          write("");
>      }
>      writeln(result); // does not compile: x.opApply matches more than
> one declaration
>      +/
> }
>
> Can someone explain me, why the compiler cannot resolve the right
> opApply? From what I know, it generates a delegate with inferred pure
> attribute and looks for the best match of opApply. Why does the manual
> rewrite work? If I've done the rewrite improperly, please tell me.

I think it's a bug. foreach and opApply are specially coded in the compiler I think, so there's bound to be inconsistencies between them and normal overload rules.

-Steve
March 31, 2016
On Thursday, 31 March 2016 at 13:51:00 UTC, Steven Schveighoffer wrote:
> I think it's a bug. foreach and opApply are specially coded in the compiler I think, so there's bound to be inconsistencies between them and normal overload rules.
>
> -Steve

I have never filed a bug report. Should this be reported? How and where to do?
March 31, 2016
On 3/31/16 10:30 AM, Q. Schroll wrote:
> On Thursday, 31 March 2016 at 13:51:00 UTC, Steven Schveighoffer wrote:
>> I think it's a bug. foreach and opApply are specially coded in the
>> compiler I think, so there's bound to be inconsistencies between them
>> and normal overload rules.
>>
>
> I have never filed a bug report. Should this be reported? How and where
> to do?

https://issues.dlang.org

Select dmd as the component.

-Steve