www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5028] New: Problem with named mixins in base class and derived class

reply d-bugmail puremagic.com writes:
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 puremagic.com
        ReportedBy: i.kasiuk gmx.de


--- Comment #0 from Ivo Kasiuk <i.kasiuk 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: -------
Oct 09 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5028


Brad Roberts <braddr puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Platform|x86_64                      |x86


--- Comment #1 from Brad Roberts <braddr puremagic.com> 2011-02-06 15:40:31 PST
---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 06 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5028


Denis <verylonglogin.reg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |verylonglogin.reg gmail.com


--- Comment #2 from Denis <verylonglogin.reg gmail.com> 2012-05-04 16:51:24 MSD
---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 04 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5028


Damian <damianday hotmail.co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |damianday hotmail.co.uk


--- Comment #3 from Damian <damianday hotmail.co.uk> 2013-02-24 09:28:47 PST ---
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;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 24 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5028



--- Comment #4 from Denis Shelomovskij <verylonglogin.reg gmail.com> 2013-02-24
23:11:51 MSK ---
(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`. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 24 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5028


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-02-24
13:29:19 PST ---
(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=8785 http://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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 24 2013