Solving a constraint hiding an error in a function literal

Paul Backus snarwin at gmail.com
Fri Feb 3 18:55:18 UTC 2023


On Friday, 3 February 2023 at 12:43:54 UTC, Nick Treleaven wrote:
> Initially I thought a constraint expression like 
> `__traits(compiles, a())` should be moved to a `static if` test 
> with a helpful error message. std.algorithm.all was changed to 
> use static assert instead:
>
> https://issues.dlang.org/show_bug.cgi?id=13683
> https://github.com/dlang/phobos/pull/6607/files
>
> But that still swallows the actual compile error and just says 
> the callable doesn't work without really saying why (why isn't 
> it a unary predicate if it accepts `range.front` as an 
> argument?). Alternatively, the constraint check could be 
> removed and you will get an internal error actually stating the 
> precise error in the callable's body. But it doesn't help with 
> overloading (see below).
>
> What if there was a new trait to solve this? Suppose 
> `__traits(callable, expr, args)`, that just does IFTI (if 
> `expr` is a function template) and then checks that the 
> parameter list of `expr` accepts `args`. It does not check that 
> `expr(args)` actually compiles, it ignores any errors in the 
> body of `expr`.

I think a better solution would be to have `__traits(compiles)` 
return the error message(s) when it fails, instead of just a 
boolean `false`. Then we could write code like:

```d
enum compResult = __traits(compiles, expr);
static if (compResult) // implicitly converts to bool
{
     doStuffWith(expr);
}
else
{
     // print error message
     static assert(0, compResult.message);
}
```

Getting constraints to understand this would require compiler 
changes, but that shouldn't be *too* difficult. Might also be 
worth having `static assert(__traits(compiles, expr))`, without 
an explicit message argument, print the returned message.


More information about the Digitalmars-d mailing list