www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bug in mixin template elision

reply Bart <Bart gmail.com> writes:
import std.stdio;

interface Q
{
    void fooo();
}

mixin template X()
{
    void fooo() { }    // Comment out and behavior changes!
    void mark() { fooo(); } // Seems mark does not lazily wait to 
see if fooo is defined outside the template but uses fooo 
directly.
}

mixin template X1()
{
    void fooo() { }
}

mixin template X2()
{
    void mark() { fooo(); }
}

class A : Q
{
    void fooo() { writeln("A"); }
    mixin X;
}


class B : Q
{
     mixin X1;
     mixin X2;
     void fooo() { writeln("B"); }
}

void main()
{
     auto x = new A;
     auto y = new B;

     x.mark;
     y.mark;

}



This makes having mixin templates provide a default behavior for 
a class impossible because any functions in the template will use 
those default behaviors no matter what, even if they are 
overridden in the scope of the mixin and so it does not play nice 
with how mixin templates are suppose to elision functions.

I don't think there is any justification for such behavior 
because if one simply wanted to use a unique function one just 
uses a different identifier. The point of mixins is that they do 
underride insertions rather than override, except they don't.

This can create the problem that one thinks any outside function 
is being used but it is not.
Jun 24 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 25 June 2019 at 00:42:25 UTC, Bart wrote:
    void fooo() { }    // Comment out and behavior changes!
    void mark() { fooo(); } // Seems mark does not lazily wait 
 to see if fooo is defined outside the template but uses fooo 
 directly.
Just use void mark() { this.fooo(); } and it will use specifically the one off `this` instead of the local scope.
Jun 24 2019
parent Bart <Bart gmail.com> writes:
On Tuesday, 25 June 2019 at 01:02:27 UTC, Adam D. Ruppe wrote:
 On Tuesday, 25 June 2019 at 00:42:25 UTC, Bart wrote:
    void fooo() { }    // Comment out and behavior changes!
    void mark() { fooo(); } // Seems mark does not lazily wait 
 to see if fooo is defined outside the template but uses fooo 
 directly.
Just use void mark() { this.fooo(); } and it will use specifically the one off `this` instead of the local scope.
This does work. I'm not sure if it is the correct behavior but at least it is somewhat logical and functional.
Jun 24 2019