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