[Issue 10037] New: Compiler should not generate opEquals method implicitly

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon May 6 21:12:48 PDT 2013


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 at puremagic.com
        ReportedBy: k.hara.pg at gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg at 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: -------


More information about the Digitalmars-d-bugs mailing list