[Issue 20226] selective import in function scope fails to merge overload sets

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Sep 19 07:26:08 UTC 2019


https://issues.dlang.org/show_bug.cgi?id=20226

--- Comment #1 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
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;
}

--


More information about the Digitalmars-d-bugs mailing list