D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1451 - overloading methods by mixin in static if doesn't work
Summary: overloading methods by mixin in static if doesn't work
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Linux
: P2 normal
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2007-08-29 13:26 UTC by Leonard Dahlmann
Modified: 2014-02-15 02:18 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Leonard Dahlmann 2007-08-29 13:26:42 UTC
<code>
template Foo(T)
{
    void callme(T)
    {
    
    }
}

class Bar
{
    mixin Foo!(int) F1;
    alias F1.callme callme;
    
    static if(true)
    {
        mixin Foo!(float) F2;
        alias F2.callme callme;
    }
}

void main()
{
    Bar bar = new Bar;
    bar.callme(cast(int)0); // <- works
    bar.callme(cast(float)0); // <- fails (line 25)
}
</code>

This code fails to compile with these error messages:
test.d(25): function test.Bar.Foo!(int).callme ((int _param_0)) does not match parameter types (float)
test.d(25): Error: cannot implicitly convert expression (0) of type float to int

After commenting out the static if it compiles perfectly, like expected.
Comment 1 Alexandre Fournier 2010-06-22 03:53:05 UTC
<code>
struct A
{
        static A opCall()
        {
                A ret;
                return ret;
        }

        mixin M;
}

template M()
{
        static typeof(*this) opCall(uint i)
        {
                A ret;
                return ret;
        }
}

int main(char[][] args)
{
        A a1 = A();
        A a2 = A(42);
        return 0;
}
</code>

Line 24: function t.A.opCall () does not match parameter types (int)
Line 24: Error: expected 0 arguments, not 1

Still the same bug, simple test case above
Comment 2 Martin Nowak 2012-03-05 08:03:49 UTC
cat > bug.d << CODE
mixin template func(T)
{
    void bar(T) {}
}

mixin func!(int);
mixin func!(double);

void baz()
{
    bar(0);
    bar(1.0);
}
CODE

dmd -c bug
Comment 3 timon.gehr 2012-03-05 14:45:26 UTC
The errors in the two comments are by design.

Comment #1: mixin template members are hidden by members of the same name in the surrounding scope.

Comment #2: mixin templates introduce distinct overload sets in order to prevent accidental function hijacking.

The original bug report is valid, and the example code now compiles with DMD 2.058.

If anyone disagrees, please reopen.
Comment 4 Martin Nowak 2012-03-06 06:26:02 UTC
>Comment #2: mixin templates introduce distinct overload sets in order to
prevent accidental function hijacking.
Makes sense.

Just for the record, I tried to unroll a TypeTuple into an overloadset,
which now works fine after merging the overloads.

mixin template _visit(Nodes...) if(Nodes.length)
{
    void visit(Nodes[0] n);
    static if (Nodes.length > 1)
    {
        mixin _visit!(Nodes[1 .. $]) vi;
        alias vi.visit visit;
    }
}