Bug 15248 – Function in current module is not allowed to overload imported function

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-10-26T09:56:42Z
Last change time
2022-10-13T07:52:40Z
Assigned to
No Owner
Creator
Shriramana Sharma

Comments

Comment #0 by samjnaa — 2015-10-26T09:56:42Z
Using dmd 2.0.68.2, I try to compile the following simple function: import std.math; real round(real val, int prec) { real pow = 10 ^^ prec; return round(val * pow) / pow; } Trying to compile this I get: foo.d(5): Error: function foo.round (real val, int prec) is not callable using argument types (real) When I've imported std.math which contains round(real), the compiler should not complain about not being able to call the overload function defined in *this* module. I don't see anything in http://dlang.org/module.html that says I cannot define an overload of an imported function. I was pointed to http://dlang.org/hijack.html but even as per the rules there: 1. Perform overload resolution independently on each overload set 2. If there is no match in any overload set, then error 3. If there is a match in exactly one overload set, then go with that 4. If there is a match in more than one overload set, then error Here there is only one round(real, int) i.e. in the current module and only one round(real) i.e. in the imported module, so as per rule 3, there should be a clear resolution. Clearly when the signature of the overload in the current module is different from that in the imported module, there should be no hijacking and thus no measures needed to prevent it. Thus the compiler should not error out. Yet I am not able to compile.
Comment #1 by mxfomin — 2015-10-26T10:39:54Z
The hijack.html is rather rationale than formal spec (and thus can be interpreted in different ways), but in the beginning it contains: The first stab at fixing this problem in the D programming language was to add the rules: 1. by default functions can only overload against other functions in the same module 2. if a name is found in more than one scope, in order to use it it must be fully qualified I think round() is found in several scopes and thus must be fully qualifyed. AFAIK approx. a year ago semantic of overloading what changed but I cannot find any mention in the spec or in the changelog (one of the features is ability to hijack round() by placing import inside function). Also I remember some issues were filed with complains about new behavior but they were closed as invalid - even seasoned D users were unaware of new behavior. Definetely there is a spec problem.
Comment #2 by dlang-bugzilla — 2015-10-27T10:22:59Z
You can reintroduce std.math.round to the current module's overload set using an alias: alias round = std.math.round;
Comment #3 by samjnaa — 2015-10-27T14:05:08Z
@Vladimir: Thanks, but I realize that workarounds exist. However if http://dlang.org/hijack.html is an accurate description of the hijacking prevention mechanism then the compiler (and the spec if necessary) should be fixed.
Comment #4 by razvan.nitu1305 — 2022-10-13T07:52:40Z
https://dlang.org/articles/hijack.html#overload-sets correctly describes the mechanism. In your example, round is preferred so that any function that is introduced by std.math does not hijack the execution. Using the alias to introduce std.math.round is not a workaround but the de facto standard of merging overload sets. This is the described, correct behavior, therefore this bug report is not valid.