2740 – Template Mixins do not work as advertised

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2740 - Template Mixins do not work as advertised
Summary: Template Mixins do not work as advertised
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 All
: P2 critical
Assignee: No Owner
URL:
Keywords: accepts-invalid, patch
Depends on:
Blocks:
Reported: 2009年03月17日 21:13 UTC by Andrew Livesay
Modified: 2015年06月09日 05:11 UTC (History)
6 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Andrew Livesay 2009年03月17日 21:13:34 UTC
// 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"
}
Comment 1 Andrew Livesay 2009年03月17日 21:31:21 UTC
Issue appears to be dependent on the order the mixin is imported. If you redefine foo() before "mixin TFoo;", it works as expected.
Comment 2 David Simcha 2010年09月08日 10:40:17 UTC
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.
Comment 3 David Simcha 2010年09月08日 10:42:34 UTC
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
}
Comment 4 Bruno Medeiros 2010年12月03日 06:33:18 UTC
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 
Comment 5 anonymous4 2010年12月03日 11:57:37 UTC
The right code can't be generated for such input.
Comment 6 akb825 2011年02月19日 12:18:10 UTC
(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.
Comment 7 Kenji Hara 2011年07月09日 16:45:34 UTC
https://github.com/D-Programming-Language/dmd/pull/223 


AltStyle によって変換されたページ (->オリジナル) /