Bug 18944 – Mixing in new overloads of a function in an object won't resolve the overloads correctly

Status
RESOLVED
Resolution
INVALID
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2018-06-05T09:02:15Z
Last change time
2018-06-05T09:32:52Z
Assigned to
No Owner
Creator
Ethan Watson

Comments

Comment #0 by gooberman — 2018-06-05T09:02:15Z
Seems related to ancient issue 9235, but not quote the same. Any additional overloads of a function that are called from the object itself won't resolve. Code example at https://run.dlang.io/is/a85Lbq Changing the code so that every instance of the foo overload is mixed in results in the program compiling and running as expected. I came across this when trying to use mixins as a dodgy way to replicate C#'s partial classes. So this is quite bad as far as usability concerns go. Error strings at time of submission: onlineapp.d(26): Error: function onlineapp.LookAtMe.foo(ref float val) is not callable using argument types (int) onlineapp.d(26): cannot pass argument val of type int to parameter ref float val onlineapp.d(31): Error: function onlineapp.LookAtMe.foo(ref float val) is not callable using argument types (string) onlineapp.d(31): cannot pass argument val of type string to parameter ref float val
Comment #1 by simen.kjaras — 2018-06-05T09:32:52Z
Here's a reduced example showing the same issue: mixin template FooOne() { void foo(ref int val) {} } mixin FooOne!(); void foo(ref float val) {} unittest { int n; // Error: function foo.foo(ref float val) is not callable using argument types (int) foo(n); } This issue is covered in the documentation of the template mixin feature (https://dlang.org/spec/template-mixin.html#mixin_scope): "1. 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" It also explains how to fix the problem: "5. Alias declarations can be used to overload together functions declared in different mixins" In your example that fix would be: mixin FooOne!() f1; mixin FooTwo!() f2; alias foo = f1.foo; alias foo = f2.foo;