Bug 12778 – Aliasing opBinaryRight to opBinary works only in certain cases
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-05-21T09:32:00Z
Last change time
2014-05-31T21:16:04Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2014-05-21T09:32:31Z
I've discovered a "feature" today where I can simply alias opBinaryRight to opBinary and it will work. However it stops working when 'const' is involved. Observe:
-----
struct Vec2
{
Vec2 opBinary(string op)(Vec2 b) const
if (op == "+" || op == "-" || op == "*")
{
mixin("return Vec2(this.x " ~ op ~ " b.x, this.y " ~ op ~ " b.y);");
}
Vec2 opBinary(string op)(float s) const
if (op == "+" || op == "-" || op == "*")
{
mixin("return Vec2(s " ~ op ~ " this.x, s " ~ op ~ " this.y);");
}
alias opBinaryRight = opBinary;
float x = 0, y = 0;
}
void main()
{
Vec2 vec;
auto v1 = vec + 1; // ok
auto v2 = 1 + vec; // ok, opBinaryRight alias works!
struct S
{
void test1()
{
Vec2 v = v1 - v2; // ok
}
void test2() const
{
Vec2 v = v1 - v2; // L37: error
}
Vec2 v1, v2;
}
}
-----
test.d(37): Error: overloads const pure nothrow @nogc @safe Vec2(Vec2 b) and const (Vec2 b) both match argument list for opBinary
I don't know if supporting this kind of aliasing was a feature by design or by mistake. It's definitely nice to have it, but it fails in 'test2'. It should either be fully supported (rejects-valid) or fully rejected (accepts-invalid).
Comment #1 by k.hara.pg — 2014-05-24T08:35:15Z
https://github.com/D-Programming-Language/dmd/pull/3578
(In reply to Andrej Mitrovic from comment #0)
> I don't know if supporting this kind of aliasing was a feature by design or
> by mistake. It's definitely nice to have it, but it fails in 'test2'. It
> should either be fully supported (rejects-valid) or fully rejected
> (accepts-invalid).
If both x.opBinary(y) and y.opBinaryRight(x) found, and they are exactly same symbol, x.opBinary(y) should be preferred.
This is consistent with current opEquals behavior - if both x.opEquals(y) and y.opEquals(x) found and they call exactly same symbol, it will be resolved to x.opEquals(y).
Comment #2 by github-bugzilla — 2014-05-31T21:16:03Z