www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 10037] New: Compiler should not generate opEquals method implicitly

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037

           Summary: Compiler should not generate opEquals method
                    implicitly
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: wrong-code
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: k.hara.pg gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg gmail.com> 2013-05-06 21:12:47 PDT ---
Currently, dmd sometimes generates opEquals method for struct types implicitly.

struct S {
    bool opEquals(ref const S) { assert(0); }   // line 2
}
struct T {
    S s;
    // Compiler implicitly generates here:
    // bool opEquals(in S rhs) const { return this.s == rhs.s }
}
void test1() {
    T t;
    static assert(__traits(hasMember, T, "opEquals"));  // pass
    bool x = (t == t);  // assertion fails at line 2 in runtime
}

In above, the field s in T requires calling its opEquals for the objects
equality, therefore for the type T compiler implicitly generates opEquals
method, which runs member-wise comparison. This behavior is introduced by
fixing issue 3433.

Doing member-wise comparison itself is not an issue. But implicitly generation
of opEquals is not good behavior. For example, if we declare a simple subtype
struct,

struct Sub(TL...) {
    TL data;
    int value;
    alias value this;
}
void test2() {
    Sub!(S) lhs;
    Sub!(S) rhs;
    assert(lhs == rhs); // compilation fails!
    // We expects to be rewritten:
    //  --> lhs.value == rhs.value
    // But, is unexpectedly rewritten to:
    //  --> lhs.opEquals(rhs)
    // And it will invoke lhs.data[0] == rhs.data[0], then
    // assertion fails at T.opEquals in runtime.
}

In this case, Sub does not define opEquals explicitly, so comparison is
expected to be falled back to alias this comparison. But, implicitly generated
'opEquals' will steal the expect. It would make alias this unusable.

So, compiler must not opEquals method implicitly. Instead, equality operation
s1 == s2 should be rewritten to s1.tupleof == s2.tupleof.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 06 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |3789


--- Comment #1 from Kenji Hara <k.hara.pg gmail.com> 2013-05-06 21:19:36 PDT ---
Essentially in D, equality operation '==' should probide structural equality.
For built-in basic types, it is just same as bitwise equality. For array types,
'==' provides length and element-wise equality. For AA types, it provides
logical AND of contained elements equality. Then, for any struct types which
does not have explicit opEquals, D should provide member-wise equality.

It has been discussed long time in bug 3789, and I think it should be fixed.
But this issue is an obstacle to fix it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull


--- Comment #2 from Kenji Hara <k.hara.pg gmail.com> 2013-05-07 07:54:48 PDT ---
https://github.com/D-Programming-Language/dmd/pull/1972

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 07 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037



--- Comment #3 from github-bugzilla puremagic.com 2013-05-07 14:00:35 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/ed8f7c697d21c4d8e887f1d2b3809195a29e1e1f
fix Issue 10037 - Compiler should not generate opEquals method implicitly

https://github.com/D-Programming-Language/dmd/commit/596c1128f4de2b246d339497e1bcec70d93ffd78
Merge pull request #1972 from 9rnsr/fix3789

Issue 3789 and 10037 - [TDPL] Structs members that require non-bitwise
comparison not correctly compared

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 07 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies gmail.com


--- Comment #4 from yebblies <yebblies gmail.com> 2013-08-03 14:31:32 EST ---
Fixed?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 02 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10037


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 03 2013