[Issue 5028] New: Problem with named mixins in base class and derived class

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Oct 9 11:56:52 PDT 2010


http://d.puremagic.com/issues/show_bug.cgi?id=5028

           Summary: Problem with named mixins in base class and derived
                    class
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody at puremagic.com
        ReportedBy: i.kasiuk at gmx.de


--- Comment #0 from Ivo Kasiuk <i.kasiuk at gmx.de> 2010-10-09 11:56:25 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list