Comment #0 by destructionator — 2022-07-31T00:16:57Z
Easier to describe in code:
```
interface A {
void foo();
void foo(int);
}
mixin template C(alias impl, Iface) {
void foo(){ return impl.foo(); }
void foo(int p){ return impl.foo(p); }
}
class B : A {
A impl;
mixin C!(impl, A) c;
void foo(int) {}
alias foo = c.foo;
}
```
Error: function `test.B.C!(impl, A).foo(int p)` conflicts with previous declaration at test.d(14)
This pattern normally works to selectively override a function from the mixin template, but the circular definition seems to trigger an order of semantic bug or something.
Comment #1 by destructionator — 2022-07-31T00:19:46Z
Actually, I don't think I completely reduced this; you can remove the alias param and still get it by just mentioning `impl` in the body.
This is further reduced:
```
interface A {
void foo();
void foo(int);
}
mixin template C() {
void foo(){ return impl.foo(); }
void foo(int p){ return impl.foo(p); }
}
class B : A {
A impl;
mixin C!() c;
void foo(int) {}
alias foo = c.foo;
}
```
The alias line in the class is necessary to trigger the thing.
Comment #2 by razvan.nitu1305 — 2022-08-09T12:55:24Z
(In reply to Adam D. Ruppe from comment #1)
> Actually, I don't think I completely reduced this; you can remove the alias
> param and still get it by just mentioning `impl` in the body.
>
> This is further reduced:
>
> ```
> interface A {
> void foo();
> void foo(int);
> }
>
> mixin template C() {
> void foo(){ return impl.foo(); }
> void foo(int p){ return impl.foo(p); }
> }
>
> class B : A {
> A impl;
> mixin C!() c;
> void foo(int) {}
> alias foo = c.foo;
> }
> ```
>
> The alias line in the class is necessary to trigger the thing.
Hmm, to me it seems that you are trying to insert `void foo(int p)` in the same overload set as `void foo(int)`. Shouldn't this be illegal? Otherwise, once you call B.foo how can the compiler know which function should be called?
Comment #3 by destructionator — 2022-08-09T13:04:17Z
The overload set merging actually works perfectly fine. Declarations in the class itself override things that are mixed in, so it will always call the one from the class if the arguments match.
The problem here is the compiler doesn't allow it with the specific scenario when you are trying to forward the call to a member variable.
Comment #4 by robert.schadek — 2024-12-13T19:24:03Z