May 16, 2018
On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
> On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer wrote:
>> [snip]
>>
>> It seems opDispatch isn't being used in the with statement. That seems like a bug, or maybe a limitation. I'm not sure how "with" works, but I assumed it would try calling as a member, and then if it doesn't work, try the call normally. Probably it's checking to see if it has that member first.
>>
>> Annoying...
>>
>> -Steve
>
> Looks like with statements ignore opDispatch.
>
> struct Foo(int x)
> {
>     auto opDispatch(string s)()
>         if (s == "bar")
>     {
>         return x++;
>     }
> }
>
>
> void main()
> {
>     int y = 0;
>     with(Foo!1)
>     {
>         y = bar; //error: undefined identifier bar
>     }
>     assert(y == 2);
> }

You've got bugs in your code: ++x has to fail for the template case, since you're trying to increment a compile-time value. This is what the call to bar is lowered to:

    Foo!1.opDispatch!"bar"()

When you try and compile that, you get these error messages:

Error: cannot modify constant 1
Error: template instance `foo.Foo!1.Foo.opDispatch!"bar"` error instantiating

In addition, the with-statement in your code refers to the type Foo!1, not an instance of it. Fixed code:

    struct Foo(int x)
    {
        int n = x;
        auto opDispatch(string s)()
            if (s == "bar")
        {
            n++;
            return n;
        }
    }


    unittest
    {
        int y = 0;
        with(Foo!1())
        {
            y = bar; // Works!
        }
        assert(y == 2);
    }

--
  Simen
May 16, 2018
On Wednesday, 16 May 2018 at 09:01:29 UTC, Simen Kjærås wrote:
> snip]
>
>     struct Foo(int x)
>     {
>         int n = x;
>         auto opDispatch(string s)()
>             if (s == "bar")
>         {
>             n++;
>             return n;
>         }
>     }
>
>
>     unittest
>     {
>         int y = 0;
>         with(Foo!1())
>         {
>             y = bar; // Works!
>         }
>         assert(y == 2);
>     }
>
> --
>   Simen

Thanks for catching that. Any idea why the original was having problems?
May 16, 2018
On Wednesday, 16 May 2018 at 10:51:51 UTC, jmh530 wrote:
> On Wednesday, 16 May 2018 at 09:01:29 UTC, Simen Kjærås wrote:
>> snip]
>>
>>     struct Foo(int x)
>>     {
>>         int n = x;
>>         auto opDispatch(string s)()
>>             if (s == "bar")
>>         {
>>             n++;
>>             return n;
>>         }
>>     }
>>
>>
>>     unittest
>>     {
>>         int y = 0;
>>         with(Foo!1())
>>         {
>>             y = bar; // Works!
>>         }
>>         assert(y == 2);
>>     }
>>
>> --
>>   Simen
>
> Thanks for catching that. Any idea why the original was having problems?

Seems to me there's an issue with overload priority - we expect opDispatch to count before globals, but it doesn't. Filed an issue: https://issues.dlang.org/show_bug.cgi?id=18866

--
  Simen
May 16, 2018
On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
>     auto opDispatch(string s)()
>         if (s == "bar")

In case anyone isn't aware, this is better written:

auto opDispatch(string s : "bar")()
1 2 3 4
Next ›   Last »