D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7779 - D1-style opWhatever method is chosen in preference to opBinary under D2
Summary: D1-style opWhatever method is chosen in preference to opBinary under D2
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2012-03-25 15:07 UTC by Stewart Gordon
Modified: 2019-07-16 04:01 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Stewart Gordon 2012-03-25 15:07:57 UTC
DMD 2.058, Win32

http://dlang.org/operatoroverloading.html#Binary

`The expression:

a op b

is rewritten as both:

a.opBinary!("op")(b)
b.opBinaryRight!("op")(a)

and the one with the ‘better’ match is selected. It is an error for both to equally match.`

No mention of opAdd, etc. in there.  Nonetheless, if such a method is present, it is chosen instead of behaving according to spec:
----------
import std.stdio;

class Qwert {
    Qwert opBinary(string op : "+")(Qwert yuiop) {
        puts("opBinary");
        return yuiop;
    }
    
    Qwert opAdd(Qwert yuiop) {
        puts("opAdd");
        return this;
    }
}

void main() {
    Qwert asdfg = new Qwert;
    asdfg = asdfg + asdfg;
}
----------
C:\Users\Stewart\Documents\Programming\D\Tests>opbinary_opadd
opAdd
----------
(DMD 2.058 Win32)

The spec gives opBinary/opBinaryRight as the way the AddExpression is resolved; yet the compiler does something else instead.

It might be reasonable as as backward compatibility measure for the opAdd to be used as a fallback if there's no matching opBinary or opBinaryRight.  But it's undocumented behaviour.  When a matching opBinary is present, by allowing an undocumented feature to override a documented one the compiler is going against the spec.

Swapping the order opBinary and opAdd in the code doesn't change the behaviour.
Comment 1 Mathias LANG 2019-07-16 04:01:30 UTC
This was "fixed" by deprecating D1-style operator overloads: https://github.com/dlang/dmd/pull/10130