[Issue 15354] unstable operator overloading with mixin expression

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Fri Jul 8 09:06:02 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=15354

Artem Borisovskiy <kolos80 at bk.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kolos80 at bk.ru

--- Comment #1 from Artem Borisovskiy <kolos80 at bk.ru> ---
This is broken with any overloads, not only for operators. Stumbled upon it
today, trying to implement a Visitor pattern for my toy language compiler.
Here's a simplified version of it:

//-------------------------
abstract class Expression {
    void accept(CodeVisitor visitor);
}

class Identifier: Expression {
    override void accept(CodeVisitor visitor) {
        visitor.visit(this);
    }
}

class BinaryExpr: Expression {
    Expression left, right;
    override void accept(CodeVisitor visitor) {
        left.accept(visitor);
        right.accept(visitor);
        visitor.visit(this);
    }
}

class Unit {}

abstract class CodeVisitor {
    mixin template NotImplementedVisit(T: Expression) {
        void visit(T expr) {
            assert(0);
        }
    }

    void visit(Unit unit) {
        assert(0);
    }

    mixin NotImplementedVisit!Identifier;
    mixin NotImplementedVisit!BinaryExpr;
}
//-------------------------

Although this is perfectly fine to me, DMD doesn't agree:

src/issue15354.d(7,22): Error: function issue15354.CodeVisitor.visit (Unit
unit) is not callable using argument types (Identifier)
src/issue15354.d(16,22): Error: function issue15354.CodeVisitor.visit (Unit
unit) is not callable using argument types (BinaryExpr)

But if I implement each overload in CodeVisitor manually, it works just fine:

//-------------------------
abstract class CodeVisitor {
    void visit(Unit unit) {
        assert(0);
    }

    void visit(Identifier expr) {
        assert(0);
    }

    void visit(BinaryExpr expr) {
        assert(0);
    }
}
//-------------------------


P.S. for Kenji:
I was quite surprised when your test case ran just fine, then I saw your
comment and realised that you were actually testing for invalid behaviour.
Please don't do that, tests are supposed to test valid behaviour, so you should
have wrote it the other way around, so it fails today, but succeeds when the
bug is fixed. It would make maintainer's life easier, if he can just copy your
test case to compiler's test suite.

--


More information about the Digitalmars-d-bugs mailing list