// As I understand TFM, all three calls to go() should be printing 'false'. import std.stdio; interface IFooable { bool foo(); } template TFoo() { bool foo() { return true; } } class Foo : IFooable { mixin TFoo; bool foo() { return false; } } class _Foo : IFooable { mixin TFoo; } class Foo2 : _Foo { bool foo() { return false; } } class Foo3 : IFooable { bool foo() { return false; } } void go(IFooable p) { writefln(p.foo); } void main() { Foo p = new Foo(); Foo2 p2 = new Foo2(); Foo3 p3 = new Foo3(); go(p); // output is "true" <------- Why isn't this false? go(p2); // output is "false" go(p3); // output is "false" }
Issue appears to be dependent on the order the mixin is imported. If you redefine foo() before "mixin TFoo;", it works as expected.
This seems to happen iff the class is called from its interface handle: import std.stdio; interface IFooable { bool foo(); } mixin template TFoo() { override bool foo() { return true; } } class Foo : IFooable { mixin TFoo; override bool foo() { return false; } } void go(IFooable p) { writeln(p.foo); } void main() { Foo p = new Foo(); go(p); // true writeln(p.foo); // false IFooable i = p; writeln(i.foo); // true } Marking as critical because this is an extremely subtle wrong-code bug that can lead to some pretty frustrating debugging.
Oh yeah, doesn't happen for abstract classes either. Looks like only the interface vtbl info is wrong. import std.stdio; abstract class IFooable { abstract bool foo(); } mixin template TFoo() { override bool foo() { return true; } } class Foo : IFooable { mixin TFoo; override bool foo() { return false; } } void go(IFooable p) { writeln(p.foo); } void main() { Foo p = new Foo(); go(p); // false writeln(p.foo); // false IFooable i = p; writeln(i.foo); // false }
Hum, I suspect the code above should not even compile. Instantiating the mixin "is analogous to cutting and pasting the body of the template into the location of the mixin." http://www.digitalmars.com/d/2.0/template-mixin.html Thus it should be the same as: class Foo : IFooable { bool foo() { return false; } bool foo() { return false; } } which should be a semantic error, I think. See http://d.puremagic.com/issues/show_bug.cgi?id=5312
The right code can't be generated for such input.
(In reply to comment #4) > Hum, I suspect the code above should not even compile. Instantiating the mixin > "is analogous to cutting and pasting the body of the template into the location > of the mixin." http://www.digitalmars.com/d/2.0/template-mixin.html > Thus it should be the same as: > > class Foo : IFooable { > bool foo() { return false; } > bool foo() { return false; } > } > > > which should be a semantic error, I think. See > http://d.puremagic.com/issues/show_bug.cgi?id=5312 From http://www.digitalmars.com/d/2.0/template-mixin.html: "The declarations in a mixin are ‘imported’ into the surrounding scope. 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." In other words, declarations in the current scope always hide declarations in the mixin.
https://github.com/D-Programming-Language/dmd/pull/223
https://github.com/D-Programming-Language/dmd/commit/4081225e4407ca08d6c8f9a390e1bb6def057c29 https://github.com/D-Programming-Language/dmd/commit/73e600b38ec0fdcadd3855db4b0ccac53a451da0
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル