Thread overview
bug in mixin template elision
Jun 25, 2019
Bart
Jun 25, 2019
Adam D. Ruppe
Jun 25, 2019
Bart
June 25, 2019
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.



June 25, 2019
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.
June 25, 2019
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.