Bug 4576 – [tdpl] 0/1 argument calls to overloaded function is allowed in presence of variadic function

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2010-08-03T12:27:15Z
Last change time
2022-08-15T12:20:28Z
Keywords
accepts-invalid, TDPL
Assigned to
No Owner
Creator
Andrej Mitrovic

Comments

Comment #0 by andrej.mitrovich — 2010-08-03T12:27:15Z
According to TDPL, this should be an ambiguous call and issue a compiler error: import std.algorithm, std.array, std.stdio; @property bool empty(T)(T[] a) { return a.length == 0; } @property ref T front(T)(T[] a) { return a[0]; } void popFront(T)(ref T[] a) { a = a[1 .. $]; } V reduce(alias fun, V, R)(V x, R range) { for ( ; !range.empty; range.popFront()) { x = fun(x, range.front); } return x; } double average() { return 2.0; } double average(double) { return 3.0; } // compute the avg of a set of numbers, passable directly or via an array double average(double[] values...) { if (values.empty) { throw new Exception("Average of zero elements is undefined"); } return reduce!((a, b) { return a + b; })(0.0, values) / values.length; } unittest { average(); // This should not compile, but does writeln(average()); // calls average(), returns 2.0 writeln(average(0)); // calls average(double), returns 3.0 assert(average(0) == 0); // fails, since it calls average() which returns 2.0 assert(average(1, 2) == 1.5); assert(average(1, 2, 3) == 2); // passing arrays and slices works too double[] v = [1, 2, 3]; assert(average(v) == 2); } void main() { }
Comment #1 by andrej.mitrovich — 2010-08-03T12:29:27Z
Sorry for the mixed comments between TDPL and the ones I've added. The average(); call should issue a compiler error. And a 1-argument call average(0) should issue an error as well.
Comment #2 by nfxjfg — 2010-08-03T12:42:42Z
Keywords go into keyword field.
Comment #3 by andrej.mitrovich — 2010-08-03T12:54:15Z
(In reply to comment #2) > Keywords go into keyword field. Ah, thanks!
Comment #4 by andrej.mitrovich — 2013-09-17T12:48:04Z
Reduced test-case: ----- void test(int[] arr...) { assert(1); } void test() { assert(0); } // hijacks (shadows) above function void main() { test(); // should fail at CT, not RT. } ----- Comment out the second function and the first one will be called. The `test()` call should be ambiguous and issue a compile-time error.
Comment #5 by razvan.nitu1305 — 2022-08-15T12:20:28Z
(In reply to Andrej Mitrovic from comment #4) > Reduced test-case: > > ----- > void test(int[] arr...) { assert(1); } > void test() { assert(0); } // hijacks (shadows) above function > > void main() > { > test(); // should fail at CT, not RT. > } > ----- > > Comment out the second function and the first one will be called. The > `test()` call should be ambiguous and issue a compile-time error. The compiler sees that both functions match, however, the non-variadic one is more specialized and the variadic one. This is all described very well in the spec [1]. More specifically, point 5 in the section that I linked. Closing as invalid. [1] https://dlang.org/spec/function.html#function-overloading