Thread overview
[Issue 8983] New: Overload introduced behind mixin template can't be called from another overload
Nov 08, 2012
Manu
Nov 08, 2012
Walter Bright
Nov 08, 2012
Walter Bright
Nov 09, 2012
Max Samukha
Nov 09, 2012
Maxim Fomin
Nov 09, 2012
Max Samukha
Nov 09, 2012
Maxim Fomin
Nov 09, 2012
Max Samukha
Nov 09, 2012
Max Samukha
November 08, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983

           Summary: Overload introduced behind mixin template can't be
                    called from another overload
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: turkeyman@gmail.com


--- Comment #0 from Manu <turkeyman@gmail.com> 2012-11-08 14:24:24 PST ---
http://dpaste.dzfl.pl/f955d02a

test(int) can't call the overload text(int, float) introduced behind the mixin
template.
If you paste that mixin directly (remove the mixin template) it works.

Again here:

mixin template MixOverload()
{
    mixin( "int test(int x, float y) { return x + cast(int)y; }" );
}

struct Test
{
    mixin MixOverload; // <- introduce an overload for test()


    void test(int x)
    {
        test(x, 1);    // call the overload defined in the mixin
    }
}

Output:

/home/c950/c254.d(13): Error: function c254.Test.test (int x) is not callable
using argument types (int,int)
/home/c950/c254.d(13): Error: function c254.Test.test (int x) is not callable
using argument types (int,int)
/home/c950/c254.d(13): Error: expected 1 arguments, not 2 for non-variadic
function type void(int x)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> 2012-11-08 14:54:35 PST ---
This actually isn't a bug. Inserting a template mixin creates a new nested scope, and names not in that nested scope override the ones in it.

Your code can be made to work in two ways. But first we need to give a name to the nested scope:

    mixin MixOverload;

becomes:

    mixin MixOverload nn;

Now, the mixin template names can be prefixed with nn:

    void test(int x)
    {
        nn.test(x, 1);    // call the overload defined in the mixin
    }

which works. Alternatively, the nested scope can be aliased into the current scope with:

    alias nn.test test;

and now:

    void test(int x)
    {
        test(x, 1);    // call the overload defined in the mixin
    }

will work, as aa.test will be overloaded with test.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983


Max Samukha <samukha@voliacable.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha@voliacable.com


--- Comment #2 from Max Samukha <samukha@voliacable.com> 2012-11-09 01:43:32 PST ---
One unfortunate consequence of the nested scope rule is we cannot use unnamed mixins for adding definitions to declarations.

mixin template Foo()
{
   void foo() {}
}

class A
{
   void foo();
   mixin Foo;
}

results in undefined reference.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983


Maxim Fomin <maxim@maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxim@maxim-fomin.ru


--- Comment #3 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-11-09 02:59:41 PST ---
(In reply to comment #2)
> One unfortunate consequence of the nested scope rule is we cannot use unnamed mixins for adding definitions to declarations.
> 
> mixin template Foo()
> {
>    void foo() {}
> }
> 
> class A
> {
>    void foo();
>    mixin Foo;
> }
> 
> results in undefined reference.

Even if there were no nested scope, this still would not work because function with omitted body is expected to appear in another object file:

class A
{
   void foo();
   void foo() {}
}

void main()
{
    (new A).foo;
}

will fail because foo matches "both foo and foo". This contradicts to C practice and does not make sense because dmd artificially creates ambiguity between function declaration and its own body. I complained in Bugzilla but was told that such practice in redundant in C and need not supported even as enhancement.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983



--- Comment #4 from Max Samukha <samukha@voliacable.com> 2012-11-09 04:34:35 PST ---
(In reply to comment #3)

> 
> Even if there were no nested scope, this still would not work because function with omitted body is expected to appear in another object file:
> 

That changed recently. Now

class A
{
    void foo();
    void foo() {  }

    void bar();
    mixin(q{ void bar() {} });
}

void main()
{
    auto a = new A;
    a.foo();
    a.bar();
}

works as expected.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983



--- Comment #5 from Maxim Fomin <maxim@maxim-fomin.ru> 2012-11-09 04:38:29 PST ---
(In reply to comment #4)
> (In reply to comment #3)
> 
> > 
> > Even if there were no nested scope, this still would not work because function with omitted body is expected to appear in another object file:
> > 
> 
> That changed recently. Now
> 
> class A
> {
>     void foo();
>     void foo() {  }
> 
>     void bar();
>     mixin(q{ void bar() {} });
> }
> 
> void main()
> {
>     auto a = new A;
>     a.foo();
>     a.bar();
> }
> 
> works as expected.

Do you compile it with version from git? Dmd 2.060 rejects this. When it was fixed?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983



--- Comment #6 from Max Samukha <samukha@voliacable.com> 2012-11-09 04:46:29 PST ---
(In reply to comment #5)
git

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8983



--- Comment #7 from Max Samukha <samukha@voliacable.com> 2012-11-09 04:53:18 PST ---
Note that variable definitions still fail:

extern int x;
int x; // conflict

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------