Skip to content

Commit

Permalink
Fix Issue 17674 - [REG 2.064] Simultaneous opBinary and opBinaryRight…
Browse files Browse the repository at this point in the history
… is not rejected
  • Loading branch information
RazvanN7 committed Nov 6, 2018
1 parent 55094b1 commit 68559e5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
28 changes: 25 additions & 3 deletions src/dmd/opover.d
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ extern (C++) Expression op_overload(Expression e, Scope* sc)
args2[0] = e.e2;
expandTuples(&args2);
argsset = 1;
Match m;
Match m, m1;
m.last = MATCH.nomatch;
if (s)
{
Expand All @@ -891,13 +891,34 @@ extern (C++) Expression op_overload(Expression e, Scope* sc)
FuncDeclaration lastf = m.lastf;
if (s_r)
{
functionResolve(&m, s_r, e.loc, sc, tiargs, e.e2.type, &args1);
if (m.lastf && (m.lastf.errors || m.lastf.semantic3Errors))
functionResolve(&m1, s_r, e.loc, sc, tiargs, e.e2.type, &args1);
if (m1.lastf && (m1.lastf.errors || m1.lastf.semantic3Errors))
{
result = new ErrorExp();
return;
}
}

/* https://issues.dlang.org/show_bug.cgi?id=17674
*
* `Match m` cannot be used to check both `s` and `s_r`
* because the opBinary functions may have different parameters.
* To fix this, two Match instances are used and merged into `m`.
*/
if (m.count && m1.count)
{
// if both m1 and m have found overloads, check which is the better match
if (m.last > m1.last)
m = m1;
else if (m1.last == m.last)
{
m.count += m1.count;
m.nextf = m1.lastf;
}
}
else if (!m.count && m1.count)
m = m1;

if (m.count > 1)
{
// Error, ambiguous
Expand All @@ -909,6 +930,7 @@ extern (C++) Expression op_overload(Expression e, Scope* sc)
if (tiargs)
goto L1;
}

if (e.op == TOK.plusPlus || e.op == TOK.minusMinus)
{
// Kludge because operator overloading regards e++ and e--
Expand Down
22 changes: 22 additions & 0 deletions test/fail_compilation/fail17674.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail17674.d(21): Error: overloads `pure nothrow @nogc @safe int(S2 other)` and `pure nothrow @nogc @safe int(S1 other)` both match argument list for `opBinary`
---
*/

// https://issues.dlang.org/show_bug.cgi?id=17674
struct S1
{
int opBinary(string op)(S2 other) { return 3; }
}

struct S2
{
int opBinaryRight(string op)(S1 other) { return 4; }
}

void main()
{
auto x = S1.init + S2.init;
}

0 comments on commit 68559e5

Please sign in to comment.