Calling function explicitly from mixin template results in recursive call instead

aliak something at something.com
Mon Dec 10 21:16:23 UTC 2018


On Sunday, 9 December 2018 at 18:36:50 UTC, Dennis wrote:
> I'm using Adam's workaround from 
> https://issues.dlang.org/show_bug.cgi?id=19365, but now I have 
> endless recursion. Reduced code:
>
> ```
> mixin template operators() {
>     S opBinary(string op: "+")(S rhs) {
>         return rhs;
>     }
>
>     // (A)
>     auto opBinary(string op, T)(T rhs) if (false) {
>         return rhs;
>     }
> }
>
> struct S {
>     mixin operators ops;
>     S opBinary(string op, T)(T a) {
>         return ops.opBinary!op(a);
>     }
> }
>
> void main() {
>     S.init.opBinary!"+"(S.init);
> }
> ```
>
> Believe it or not, `ops.opBinary!op(a);` doesn't call anything 
> from the mixin template ops, but it calls itself and it results 
> in a stack overflow. I think this is a bug, but last time I was 
> wrong, so maybe someone can explain what's going on here.

I think the docs [0] are not as specific as they can be, but 
there's this part: "If the name of a declaration in a mixin is 
the same as a declaration in the surrounding scope, the 
surrounding declaration overrides the mixin one". Later on 
there's a section on disambiguating between conflicting symbols, 
but that sections feels wanting. Furthremore, this seems to work 
as expected:

mixin template Foo() {
     void f() {
         writeln("Foo.f");
     }
}

mixin Foo foo;
void f() {
     writeln("f");
     foo.f;
}

void main() {
     f;
}

I think I'd file this and see if someone complains.


>
> Does anyone know how to get this working?

Does this fix your issue?

struct S {
     mixin operators ops;
     S opBinary(string op, T)(T a) {
         alias opBinary = ops.opBinary; // explicitly alias 
opBinary in this scope
         return opBinary!op(a);
     }
}

Cheers,
- Ali

[0] https://dlang.org/spec/template-mixin.html#mixin_scope


More information about the Digitalmars-d-learn mailing list