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;