Thread overview
SumType alias can't be deduced?
Feb 21, 2022
Emmanuelle
Feb 21, 2022
Paul Backus
Feb 21, 2022
Emmanuelle
February 21, 2022

See https://run.dlang.io/is/hNaSFh:

import std.sumtype;

struct Unit {}
alias Option(T) = SumType!(T, Unit);

void foobar(T)(Option!T option) {}

void main() {
    foobar(Option!int(123));
}

If you run this, the compiler should emit this error:

onlineapp.d(14): Error: template `onlineapp.foobar` cannot deduce function from argument types `!()(SumType!(int, Unit))`
onlineapp.d(8):        Candidate is: `foobar(T)(Option!T option)`

If you change foobar’s parameter’s type from Option!T to SumType!(T, Unit), it compiles without error.

Surely this is not intended? Is this a compiler bug or am I doing something wrong?

Cheers!

February 21, 2022

On Monday, 21 February 2022 at 18:43:18 UTC, Emmanuelle wrote:

>

If you run this, the compiler should emit this error:

onlineapp.d(14): Error: template `onlineapp.foobar` cannot deduce function from argument types `!()(SumType!(int, Unit))`
onlineapp.d(8):        Candidate is: `foobar(T)(Option!T option)`

If you change foobar’s parameter’s type from Option!T to SumType!(T, Unit), it compiles without error.

This is a long-standing limitation of the D compiler's template argument deduction: it cannot "see through" alias templates to deduce the underlying type.

The enhancement request to make this work was submitted in 2008: https://issues.dlang.org/show_bug.cgi?id=1807

Unfortunately, getting the compiler to handle this correctly is much harder than it looks, and nobody has managed to do it yet, though several have tried.

As a workaround, you can define your Optional type using a struct instead of an alias:

import std.sumtype;

struct Unit {}
struct Option(T) {
    SumType!(T, Unit) data;
    this(U, this This)(U value)
    {
        data = value;
    }
    alias data this;
}

void foobar(T)(Option!T option) {}

void main() {
    foobar(Option!int(123));
}
February 21, 2022

On Monday, 21 February 2022 at 20:18:46 UTC, Paul Backus wrote:

>

This is a long-standing limitation of the D compiler's template argument deduction: it cannot "see through" alias templates to deduce the underlying type.

Oh, that’s an unfortunate limitation but at least there’s a workaround. Thank you!