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

Reply via email to