Bug 8074 – template-mixin example contradicts text

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-05-09T09:52:00Z
Last change time
2014-04-24T23:03:04Z
Keywords
pull, spec
Assigned to
andrej.mitrovich
Creator
tim.dolores

Comments

Comment #0 by tim.dolores — 2012-05-09T09:52:31Z
The text says: "If two different mixins are put in the same scope, and each define a declaration with the same name, there is an ambiguity error when the declaration is referenced" However, the example *does* compile with no error, and runs the Bar.func() method. Here is the exact code I'm using: $ cat mix08.d import std.stdio, std.exception; /* If two different mixins are put in the same scope, and each define a declaration with the same name, there is an ambiguity error when the declaration is referenced: */ mixin template Foo() { int x = 5; void func(int x) { writeln("Foo.func(), x = ", x); } } mixin template Bar() { int x = 4; void func() { writeln("Bar.func(), x = ", x); } } mixin Foo; mixin Bar; void main() { //writefln("x = %d", x); // error, x is ambiguous /* The call to func() is ambiguous because Foo.func and Bar.func are in different scopes. */ func(); // error, func is ambiguous } $ dmd|grep DMD DMD64 D Compiler v2.059 $ dmd -w mix08.d $ ./mix08 Bar.func(), x = 4 $ I don't know if the text is wrong, or if DMD is wrong.
Comment #1 by tim.dolores — 2012-05-09T09:54:19Z
I forgot to link to the exact spec page I'm talking about: http://dlang.org/template-mixin.html
Comment #2 by andrej.mitrovich — 2013-02-06T20:22:31Z
I seriously doubt we could implement this now without breaking code. Chances are people are using it to inject multiple function overloads. I think we'll simply have to edit that part out of the website. Andrei do you agree?
Comment #3 by andrei — 2013-02-07T09:21:17Z
We should fix this, it's clearly a crass error. We can't afford to arbitrarily pick the last lexical declaration in case of an ambiguity.
Comment #4 by andrej.mitrovich — 2013-02-07T09:53:20Z
(In reply to comment #3) > We should fix this, it's clearly a crass error. We can't afford to arbitrarily > pick the last lexical declaration in case of an ambiguity. But there is no ambiguity, the two functions are: void func(int x) { writeln("Foo.func(), x = ", x); } void func() { writeln("Bar.func(), x = ", x); } Neither of these can hijack one another.
Comment #5 by andrej.mitrovich — 2013-02-07T09:54:00Z
(In reply to comment #4) > (In reply to comment #3) > > We should fix this, it's clearly a crass error. We can't afford to arbitrarily > > pick the last lexical declaration in case of an ambiguity. > > But there is no ambiguity, the two functions are: > > void func(int x) { writeln("Foo.func(), x = ", x); } > void func() { writeln("Bar.func(), x = ", x); } > > Neither of these can hijack one another. Edit: Well except the case of taking the address of such a function which could prove problematic.
Comment #6 by k.hara.pg — 2013-02-14T09:01:34Z
I think there is no ambiguity for current behavior. I can explain it based on the 'overload set resolution rule'. Please regard these mixin declarations as two import statements. mixin Foo; mixin Bar; void main() { func(); } Can be considered to: import foo; import bar; void main() { func(); } And each module contains following declarations. module foo; // --- int x = 5; void func(int x) { writeln("Foo.func(), x = ", x); } module bar; // --- int x = 4; void func() { writeln("Bar.func(), x = ", x); } Finally, the 'func()' is resolved to the call of bar.func. "compiler will resolve an ambiguous mixin-ed symbol by regarding it as overload set.." - This is much reasonable and consistent rule. If 'foo' is called with some arguments but cannot eliminate the ambiguity, it will be error. Otherwise simply will succeed to call.
Comment #7 by code — 2013-05-20T11:34:15Z
(In reply to comment #6) > I can explain it based on the 'overload set resolution rule'. Yes, according to http://dlang.org/template-mixin.html these form an overload set and only one of the sets has a match. (In reply to comment #5) > Edit: Well except the case of taking the address of such a function which could > prove problematic. No problem here, you just have to specify the function type. void foo() {} void foo(int) {} void main() { void function() a1 = &foo; void function(int) a2 = &foo; auto b1 = cast(void function())&foo; auto b2 = cast(void function(int))&foo; assert(cast(void*)a1 !is cast(void*)a2); assert(a1 is b1); assert(a2 is b2); }
Comment #8 by dlang-bugzilla — 2014-03-20T09:12:45Z
I noticed this behavior today: ///////// test.d //////// template T() { void foo(string s) {} } void foo() {} mixin T; void main() { foo("Test"); } ///////////////////////// This will not compile - the module-level foo hides the mixed-in one, which essentially makes the mixin a noop. Is this intentional? It makes it impossible to use mixins to generate additional overloads for a function.
Comment #9 by andrej.mitrovich — 2014-04-23T11:11:35Z
Comment #10 by github-bugzilla — 2014-04-24T23:03:03Z
Commits pushed to master at https://github.com/D-Programming-Language/dlang.org https://github.com/D-Programming-Language/dlang.org/commit/d76808ead49e1dc560ec2be1462cf3b812e62891 Fix Issue 8074 - Template-mixin example contradicts text. https://github.com/D-Programming-Language/dlang.org/commit/b11d0672ac9881cbdf026dadd787efa3ec2f16a9 Merge pull request #559 from AndrejMitrovic/Fix8074 Issue 8074 - Template-mixin example contradicts text.