Thread overview
opIn_r not detected
Feb 10, 2011
spir
Feb 10, 2011
spir
Feb 10, 2011
Stewart Gordon
Feb 10, 2011
spir
Feb 12, 2011
Stewart Gordon
February 10, 2011
Hello,

Implicite deref of struct pointers on member access works fine for data, methods, even special methods with language semantics like opEquals (see example below).
But I cannot have 'in' work with method opIn_r. I get:
    Error: rvalue of in expression must be an associative array, not S*
What do I have wrong? Or is it a bug: the compiler does not even search the struct for opIn_r? But then, why does it do it for opEquals?

Denis

struct S {
    int i;
    void show() { writeln(i); }
    const bool opEquals (ref const(S) s) {
        writeln("==");
        return (i == s.i);
    }
    bool opIn_r (int j) { return (i==j); }
}
unittest {
    S* sp = &(S(1));
    writeln(sp.i);
    sp.show();
    S s2 = S(1);
    writeln(sp == s2);
    writeln(1 in sp);
}

-- 
_________________
vita es estrany
spir.wikidot.com

February 10, 2011
On Thu, 10 Feb 2011 07:59:06 -0500, spir <denis.spir@gmail.com> wrote:

> Hello,
>
> Implicite deref of struct pointers on member access works fine for data, methods, even special methods with language semantics like opEquals (see example below).
> But I cannot have 'in' work with method opIn_r. I get:
>      Error: rvalue of in expression must be an associative array, not S*
> What do I have wrong? Or is it a bug: the compiler does not even search the struct for opIn_r? But then, why does it do it for opEquals?
>
> Denis
>
> struct S {
>      int i;
>      void show() { writeln(i); }
>      const bool opEquals (ref const(S) s) {
>          writeln("==");
>          return (i == s.i);
>      }
>      bool opIn_r (int j) { return (i==j); }
> }
> unittest {
>      S* sp = &(S(1));
>      writeln(sp.i);
>      sp.show();
>      S s2 = S(1);
>      writeln(sp == s2);
>      writeln(1 in sp);
> }
>

There is a bug in the compiler that the message says associative array is required.  There is a bugzilla issue somewhere on that...

But it does look like it should work, I'd file a separate bugzilla on the opIn_r not working.

-Steve
February 10, 2011
On 02/10/2011 02:39 PM, Steven Schveighoffer wrote:
> On Thu, 10 Feb 2011 07:59:06 -0500, spir <denis.spir@gmail.com> wrote:
>
>> Hello,
>>
>> Implicite deref of struct pointers on member access works fine for data,
>> methods, even special methods with language semantics like opEquals (see
>> example below).
>> But I cannot have 'in' work with method opIn_r. I get:
>> Error: rvalue of in expression must be an associative array, not S*
>> What do I have wrong? Or is it a bug: the compiler does not even search the
>> struct for opIn_r? But then, why does it do it for opEquals?
>>
>> Denis
>>
>> struct S {
>> int i;
>> void show() { writeln(i); }
>> const bool opEquals (ref const(S) s) {
>> writeln("==");
>> return (i == s.i);
>> }
>> bool opIn_r (int j) { return (i==j); }
>> }
>> unittest {
>> S* sp = &(S(1));
>> writeln(sp.i);
>> sp.show();
>> S s2 = S(1);
>> writeln(sp == s2);
>> writeln(1 in sp);
>> }
>>
>
> There is a bug in the compiler that the message says associative array is
> required. There is a bugzilla issue somewhere on that...
>
> But it does look like it should work, I'd file a separate bugzilla on the
> opIn_r not working.

http://d.puremagic.com/issues/show_bug.cgi?id=5558
Content reproduced below; tell me please if the description is (not) ok.

Denis

==========================================
Issue 5558 - opIn_r not detected as method for 'in' in pointed struct

In a struct, opIn_r is not detected by the compiler as beeing the method implementing the operator 'in'. Example:

struct S {
    int i;
    void show() { writeln(i); }
    const bool opEquals (ref const(S) s) {
        writeln("==");
        return (i == s.i);
    }
    bool opIn_r (int j) { return (i==j); }
}
unittest {
    S* sp = &(S(1));
    writeln(sp.i);
    sp.show();

    S s2 = S(1);
    writeln(sp == s2);
    writeln(1 in s2);

    // error:
    writeln(1 in sp);
}
==>
    Error: rvalue of in expression must be an associative array, not S*

This concerns opIn_r on pointed struct only; the other struct members of the structn and the not-pointed one are only here to contrast:
* Data members, regular methods and even "language methods" like opEquals are correctly taken into account on a struct, even via implicite deref.
* opIn_r is correctly detected as implementing 'in' on a non-pointed or explicitely dereferenced struct.

Thus, the code works fine if one comments out the very last line.

Waiting for a fix, the error message should be corrected to eg:
    Error: right operand of 'in' operation must be an associative array
           or implement the operator 'in' via method opIn_r

-- 
_________________
vita es estrany
spir.wikidot.com

February 10, 2011
On 10/02/2011 12:59, spir wrote:
> Hello,
>
> Implicite deref of struct pointers on member access works fine for data, methods, even
> special methods with language semantics like opEquals (see example below).
> But I cannot have 'in' work with method opIn_r. I get:
> Error: rvalue of in expression must be an associative array, not S*
> What do I have wrong? Or is it a bug: the compiler does not even search the struct for
> opIn_r? But then, why does it do it for opEquals?
<snip>

That got me thinking.  It would appear that it auto-dereferences only the left operand. Try adding this to your code and see:

    writeln(s2 == sp);

Stewart.
February 10, 2011
On 02/10/2011 07:43 PM, Stewart Gordon wrote:
> On 10/02/2011 12:59, spir wrote:
>> Hello,
>>
>> Implicite deref of struct pointers on member access works fine for data,
>> methods, even
>> special methods with language semantics like opEquals (see example below).
>> But I cannot have 'in' work with method opIn_r. I get:
>> Error: rvalue of in expression must be an associative array, not S*
>> What do I have wrong? Or is it a bug: the compiler does not even search the
>> struct for
>> opIn_r? But then, why does it do it for opEquals?
> <snip>
>
> That got me thinking. It would appear that it auto-dereferences only the left
> operand. Try adding this to your code and see:
>
> writeln(s2 == sp);

Works, indeed, but using opEquals on s2, and because s2 is not "pointed".

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

February 12, 2011
On 10/02/2011 22:32, spir wrote:
> On 02/10/2011 07:43 PM, Stewart Gordon wrote:
<snip>
>> That got me thinking. It would appear that it auto-dereferences only the left
>> operand. Try adding this to your code and see:
>>
>> writeln(s2 == sp);
>
> Works, indeed, but using opEquals on s2, and because s2 is not "pointed".

In what compiler version/platform?

Here's what I get (DMD 2.051, Windows, after fixing the missing import):
----------
C:\Users\Stewart\Documents\Programming\D\Tests>dmd -unittest opin_r.d
opin_r.d(19): Error: function opin_r.S.opEquals (ref const(S) s) const is not ca
llable using argument types (S*)
opin_r.d(19): Error: cannot implicitly convert expression (sp) of type S* to con
st(S)
----------

Or maybe you forgot the -unittest?

Stewart.