Bug 20226 – selective import in function scope fails to merge overload sets

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2019-09-18T12:37:09Z
Last change time
2024-12-13T19:05:37Z
Assigned to
No Owner
Creator
Simen Kjaeraas
Moved to GitHub: dmd#17923 →

Comments

Comment #0 by simen.kjaras — 2019-09-18T12:37:09Z
unittest { import std.complex : abs; import std.math : abs; // template std.complex.abs cannot deduce function // from argument types !()(int) auto a = abs(1); } Changing the order of imports above makes the code compile. Using regular imports correctly merges overload sets: unittest { import std.complex; import std.math; auto a = abs(1); } This is likely related to the restrictions on overload sets in function scopes: unittest { void fun() {} void fun(int i) {} // declaration fun is already defined }
Comment #1 by simen.kjaras — 2019-09-19T07:26:08Z
Note that even though changing the order of imports makes the above code compile, that's because std.math's abs() implementation ends up being the one available, and calling abs() on e.g. a Complex!float would fail in that case (but would compile in the above example). This same issue occurs when importing a function that also exists in a parent scope: import std.stdio; float abs(float f) { return f < 0 ? -f : f; } unittest { import std.complex : complex, abs; auto a = complex(1.0,1.0); auto b = 1.0f; writeln(abs(a)); writeln(abs(b)); } In a non-function scope, the solution is to use an alias: float abs(float f) { return f < 0 ? -f : f; } struct S { import std.complex : complex, abs; alias abs = .abs; unittest { abs(1); abs(complex(1,1)); } } However, this doesn't work inside functions: float abs(float f) { return f < 0 ? -f : f; } unittest { import std.complex : complex, abs; alias abs = .abs; // declaration abs is already defined } A workaround exists in using a non-function scope to merge the overload sets: float abs(float f) { return f < 0 ? -f : f; } unittest { import std.complex : complex, cabs = abs; alias abs = MergeOverloads!(cabs, .abs); abs(1); abs(complex(1,1)); } template MergeOverloads(T...) { static foreach (E; T) alias MergeOverloads = E; }
Comment #2 by robert.schadek — 2024-12-13T19:05:37Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17923 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB