Thread overview
Template argument deduction fails with alias
Sep 01, 2020
Ben Jones
Sep 01, 2020
Paul Backus
Sep 01, 2020
Ben Jones
Sep 01, 2020
Paul Backus
September 01, 2020
I have an alias that looks like

static if(...){
  alias AliasType = SumType!(...);
}

which I use in a template constraint for a function template:

bool func(T: AliasType!Args, Args...)(T t){ ... }


When I try to call func with an AliasType object, the argument deduction fails with a message saying that the argument type (a SumType) doesn't match the template constraint (an AliasType)

Things do work if I change the template constraint to be a SumType rather an an AliasType

Is there a workaround to this?  Here's a complete example: https://run.dlang.io/is/buRGTs

August 31, 2020
On 8/31/20 9:11 PM, Ben Jones wrote:
> I have an alias that looks like
> 
> static if(...){
>    alias AliasType = SumType!(...);
> }
> 
> which I use in a template constraint for a function template:
> 
> bool func(T: AliasType!Args, Args...)(T t){ ... }
> 
> 
> When I try to call func with an AliasType object, the argument deduction fails with a message saying that the argument type (a SumType) doesn't match the template constraint (an AliasType)
> 
> Things do work if I change the template constraint to be a SumType rather an an AliasType
> 
> Is there a workaround to this?  Here's a complete example: https://run.dlang.io/is/buRGTs
> 

Very old enhancement request (I doubt this will ever happen): https://issues.dlang.org/show_bug.cgi?id=1807

-Steve
September 01, 2020
On Tuesday, 1 September 2020 at 01:11:35 UTC, Ben Jones wrote:
> I have an alias that looks like
>
> static if(...){
>   alias AliasType = SumType!(...);
> }
>
> which I use in a template constraint for a function template:
>
> bool func(T: AliasType!Args, Args...)(T t){ ... }
>
>
> When I try to call func with an AliasType object, the argument deduction fails with a message saying that the argument type (a SumType) doesn't match the template constraint (an AliasType)
>
> Things do work if I change the template constraint to be a SumType rather an an AliasType
>
> Is there a workaround to this?  Here's a complete example: https://run.dlang.io/is/buRGTs

This is a very old known bug:

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

Attempts have been made to fix it, but the problem is a lot more complicated than it looks at first glance, so I wouldn't expect a solution any time soon.

Aside from using SumType directly in the function signature, another workaround is to use a wrapper struct instead of an alias:

    struct AliasType(Args...) {
        SumType!Args data;
        alias data this;
    }

    bool func(T : AliasType!Args, Args...)(T t) { ... }
September 01, 2020
On Tuesday, 1 September 2020 at 01:26:30 UTC, Paul Backus wrote:

>
> Aside from using SumType directly in the function signature, another workaround is to use a wrapper struct instead of an alias:
>
>     struct AliasType(Args...) {
>         SumType!Args data;
>         alias data this;
>     }
>
>     bool func(T : AliasType!Args, Args...)(T t) { ... }

Thanks all.

I tried using alias this at first and then I get errors trying to construct AliasType objects:


auto pi = Payload!int(5);
auto pe = ParseError("error");
alias PRType = ParseResult!(Payload!int, ParseError);
auto pr = PRType(pi);

gives:

cannot implicitly convert expression `pi` of type `Payload!int` to `SumType!(Payload!int, ParseError)`




September 01, 2020
On Tuesday, 1 September 2020 at 02:48:08 UTC, Ben Jones wrote:
>
> Thanks all.
>
> I tried using alias this at first and then I get errors trying to construct AliasType objects:
>
>
> auto pi = Payload!int(5);
> auto pe = ParseError("error");
> alias PRType = ParseResult!(Payload!int, ParseError);
> auto pr = PRType(pi);
>
> gives:
>
> cannot implicitly convert expression `pi` of type `Payload!int` to `SumType!(Payload!int, ParseError)`

Unfortunately, `alias this` does not apply to constructors. You can either add your own constructor to the wrapper struct:

struct ParseResult(Ts...)
{
    SumType!Ts data;
    alias data this;

    this(T)(T t)
        if (staticIndexOf!(T, data.Types) >= 0)
    {
        data = t;
    }
}

...or use a factory function like the following:

PRType parseResult(T)(T t)
{
    return PRType(SumType!(Payload!int, ParseError)(t));
}