March 16, 2023
https://issues.dlang.org/show_bug.cgi?id=23786

          Issue ID: 23786
           Summary: __traits(parent, {}) in overloaded function produces
                    wierd results dependent on declaration order
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: spoov0.707@gmail.com

### test.d ###
enum m(string s) = q{
    pragma(msg, __traits(parent, {}).mangleof);
    __traits(parent, {})(} ~ s ~  q{);
};

static if (0) // A
{
    void foo(int i) { mixin(m!"1.0"); }
    void foo(int* p) {}
    /+
    4test3foo
    test.d-mixin-8(10): Error: none of the overloads of `foo` are callable
using argument types `(double)`
    test.d(8):        Candidates are: `test.foo(int i)`
    test.d(9):                        `test.foo(int* p)`
    +/
}

static if (0) // B
{
    void foo(int i) { mixin(m!"&i"); }
    void foo(int* p) {}
    /+
    4test3foo
    Error: program killed by signal 11
    +/
}

static if (0) // C
{
    void foo(int* p) {}
    void foo(int i) { mixin(m!"&i"); }
    /+
    _D4test3fooFiZv
    test.d-mixin-31(33): Error: function `test.foo(int i)` is not callable
using argument types `(int*)`
    test.d-mixin-31(33):        cannot pass argument `& i` of type `int*` to
parameter `int i`
    +/
}

void main() { foo(1); }
##############

Enabling case A and running it with 'dmd -run test.d' prints an invalid mangle and suggests thats '__traits(parent, {})' resolves to an overload set.

Enabling case B which tries to call the other overload compiles but causes a stackoverflow because the overload calls itself.

Enabling case C that swaps the declaration order produces the correct mangle and error message.

--