www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 16415] New: Overload conflicts with mixin templates

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

          Issue ID: 16415
           Summary: Overload conflicts with mixin templates
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: kolos80 bk.ru

I'm trying to implement the Visitor pattern and utilize template mixins to
avoid boilerplate by generating visit() methods for each type. DMD goes crazy
that the two visit() overloads conflict with each other, despite overloads
accepting different types (A and B in my case):

//-----------------------------------

interface Visitor(types...)
{
    mixin generateMethods!types;

    private mixin template generateMethods(types...)
    {
        static if (types.length)
        {
            mixin generateMethod!(types[0]); // but this works: void
visit(types[0]);
            mixin generateMethods!(types[1..$]);
        }
    }

    private mixin template generateMethod(T)
    {
        void visit(T);
    }
}

alias TestVisitor = Visitor!(A, B);

mixin template AcceptVisitor()
{
    void accept(TestVisitor v)
    {
        v.visit(this);
    }
}

class A
{
    mixin AcceptVisitor;
}

class B: A 
{
    override mixin AcceptVisitor;
}

//-----------------------------------

P.S. As a side note, can we please have "static foreach" everywhere, just like
"static if"? I just want this to work:

interface Visitor(types...)
{
    static foreach (T; types)
        void visit(T);
}

But D doesn't allow that, so I'm forced to use recursive mixin templates.
"Recursive" doesn't mean "elegant" all the time, in this case it's the
opposite. Should I make a DIP or it's not gonna happen? Why is this even
forbidden in the first place?

--
Aug 22 2016