May 12, 2021

Given

import std.range.primitives : isInputRange;

enum isDumb(Args...) = (Args.length == 2 && Args.length == 3);

void f(Args...)(Args args)
if (isDumb!(Args))
{
}

void g(Arg)(Arg arg)
if (isInputRange!(Arg))
{
}

@safe pure unittest
{
    f(2, 3);
    g(2);
}

dmd diagnoses the first level as

/home/per/f.d(18,6): Error: template `f.f` cannot deduce function from argument types `!()(int, int)`, candidates are:
/home/per/f.d(6,6):        `f(Args...)(Args args)`
  with `Args = (int, int)`
  must satisfy the following constraint:
`       isDumb!Args`
/home/per/f.d(19,6): Error: template `f.g` cannot deduce function from argument types `!()(int)`, candidates are:
/home/per/f.d(11,6):        `g(Arg)(Arg arg)`
  with `Arg = int`
  must satisfy the following constraint:
`       isInputRange!Arg

I'm certain I've seen dmd be able to diagnose which sub-expression of isDumb and isInputRange that evaluated to false. Did I just dream this or is there a way? If there is a way does this improvement still reside in a dmd PR?

May 12, 2021

On Wednesday, 12 May 2021 at 12:54:24 UTC, Per Nordlöw wrote:

>

I'm certain I've seen dmd be able to diagnose which sub-expression of isDumb and isInputRange that evaluated to false. Did I just dream this or is there a way? If there is a way does this improvement still reside in a dmd PR?

It will diagnose which sub-expression of the template constraint failed, but it will not descend into templates. So, if you inline the constraint:

void f(Args...)(Args args)
if (Args.length == 2 && Args.length == 3)
{
}

You get the following error message:

onlineapp.d(18): Error: template `onlineapp.f` cannot deduce function from argument types `!()(int, int)`, candidates are:
onlineapp.d(6):        `f(Args...)(Args args)`
  with `Args = (int, int)`
  must satisfy the following constraint:
`       Args.length == 3`

It might be possible to extend this to work with simple enum templates like isDumb and isInputRange, whose bodies consist of a single boolean expression, although I expect you would run into many of the same difficulties that caused past attempts at fixing issue 1807 [1] to fail.

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