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

Kenji Hara <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Kenji Hara <[email protected]> ---
(In reply to Vladimir Panteleev from comment #1)
> Reduced:
> 
[snip]
> 
> This is a regression.
> 
> Introduced in
> https://github.com/D-Programming-Language/dmd/commit/
> acc22ce25db42facfe4917aeceabd28a410f4c95

No, it's intentional side-effect to kill cross-talks between function types
(issue 3866).

A function pointer/delegate type passed to template type parameter, cannot save
the default arguments.

Explanation code why it's necessary:

module test;

template X(FP) {}
alias x1 = X!(void function(int));
alias x2 = X!(void function(int a = 1));

pragma(msg, x1.mangleof);   // 4test12__T1XTPFiZvZ
pragma(msg, x2.mangleof);   // 4test12__T1XTPFiZvZ

A function type does not encode default arguments (it's documented in abi
page), so the two instantiations x1 and x2 needs to be mangled as identical.
For the reason, compiler intentionally strips off all default arguments in the
FP type.

Theoretically, default arguments are associated with symbols, not types. So if
you pass symbols via alias parameter, it will make different instances, and
associated default arguments will work inside template.

auto callWithoutArgs(alias f)()
{
    // f is functions or function pointer variables with default arguments.
    return f();
}
void main()
{
    int func1(int x = 1) { return x; }
    int func2(int x = 2) { return x; }
    assert(callWithoutArgs!func1() == 1);
    assert(callWithoutArgs!func2() == 2);

    int function(int x = 1) fp1 = x => x;
    int function(int x = 2) fp2 = x => x;
    assert(callWithoutArgs!fp1() == 1);
    assert(callWithoutArgs!fp2() == 2);
}

--

Reply via email to