In the following example, B.tb.f() collides with A.ta.f():
$ cat test.d
mixin template T() {
final void f(/*typeof(this) dummy=null*/) { }
}
class A {
mixin T ta;
}
class B : A {
mixin T tb;
}
void main() {
B b = new B();
b.ta.f();
b.tb.f();
}
$ dmd test
test.d(2): Error: function test.B.T!().f cannot override final function test.A.T!().f
test.d(8): Error: mixin test.B.T!() error instantiating
This can be fixed with the commented-out code in the second line.
The error also does not occur if there is a second instance of T in A.
And if f() is not declared final the code does compile but the program behaviour changes:
$ cat test.d
import std.stdio;
mixin template T(int i) {
void f() { writefln("%d", i); }
}
class A {
mixin T!(1) ta;
}
class B : A {
mixin T!(2) tb;
}
void main() {
B b = new B();
b.ta.f();
b.tb.f();
}
$ dmd test
$ ./test
2
2
So b.ta.f() actually calls b.tb.f() instead (this does not happen if f is final).
I am not sure if any of this is exactly wrong. However, I find it very hard to predict what will compile and how it will behave. In particular, the significantly different results when declaring the method final or non-final or when adding a second instance of T to A are rather surprising.
The following example uses the Signal template from std.signals and also does not behave as I would have expected:
$ cat test.d
import std.stdio;
import std.signals;
class A {
mixin Signal!() sa;
void a() { writeln("a()"); }
this() { sa.connect(&a); }
}
class B : A {
mixin Signal!() sb;
void b() { writeln("b()"); }
this() { sb.connect(&b); }
}
void main() {
B b = new B();
b.sa.emit();
b.sb.emit();
}
$ dmd test
$ ./test
a()
b()
a()
b()
Tested with DMD v2.049.
Comment #1 by braddr — 2011-02-06T15:40:31Z
Mass migration of bugs marked as x86-64 to just x86. The platform run on isn't what's relevant, it's if the app is a 32 or 64 bit app.
Comment #2 by verylonglogin.reg — 2012-05-04T05:51:24Z
The issue is that this doesn't compile:
---
mixin template T() { final void f() { } }
class A { mixin T ta; }
class B : A { mixin T tb; }
---
We need a general solution here. Looks like
---
class A { mixin T; }
class B : A { mixin T tb; }
---
and
---
class A { mixin T ta; }
class B : A { mixin T; }
---
and
---
class A { final void f() { } }
class B : A { mixin T tb; }
---
and
---
class A { mixin T ta; }
class B : A { final void f() { } }
---
should also compile.
Comment #3 by damianday — 2013-02-24T09:28:47Z
I ran into this bug using std.signals and is currently a blocker for me,
making std.signals useless, so I must use another mechanism. This is a example:
import std.signals;
class ClassA
{
public mixin Signal!(int) addNumber1;
}
class ClassB : ClassA
{
public mixin Signal!(int) addNumber2;
}
Comment #4 by verylonglogin.reg — 2013-02-24T12:11:51Z
(In reply to comment #3)
> I ran into this bug using std.signals and is currently a blocker for me,
> making std.signals useless, so I must use another mechanism. This is a example:
>
> import std.signals;
>
> class ClassA
> {
> public mixin Signal!(int) addNumber1;
> }
>
> class ClassB : ClassA
> {
> public mixin Signal!(int) addNumber2;
> }
A workaround:
Add dummy signal `private mixin Signal!(int) __dummy;` to `ClassA`.
Comment #5 by andrej.mitrovich — 2013-02-24T13:29:19Z
(In reply to comment #2)
> The issue is that this doesn't compile:
> ---
> mixin template T() { final void f() { } }
>
> class A { mixin T ta; }
> class B : A { mixin T tb; }
> ---
This would be an enhancement request though, the spec doesn't say the symbols are only visible by using 'ta' and 'tb'.
The issue name here is a misnomer, it's unrelated to base/derived classes.
See also:
http://d.puremagic.com/issues/show_bug.cgi?id=8785http://d.puremagic.com/issues/show_bug.cgi?id=8033
So this would really be an enhancement request to make symbols in mixin templates unavailable in the current scope when a mixin identifier is used:
mixin template T() { final void f() { } }
class A { mixin T ta; }
class B : A { mixin T tb; }
With the enhancement only A.ta.f() and B.tb.f() would be visible, A.f() and B.f() would be invisible.
Comment #6 by robert.schadek — 2024-12-13T17:53:52Z