Solving a constraint hiding an error in a function literal
Steven Schveighoffer
schveiguy at gmail.com
Fri Feb 3 20:20:48 UTC 2023
On 2/3/23 1:55 PM, Paul Backus wrote:
> 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.
The problem with this is that your constraint then has to become:
```d
foo(alias bar) if (__traits(compiles,
exprUsingBar).hasOnlyImplementationIssues)
```
That `hasOnlyImplementationIssues` is going to be messy, difficult to
implement, and basically redoing all that the compiler is already doing.
Plus, if it's just a string, it might have to change with compiler
versions. Essentially, changing error messages becomes a breaking change.
-Steve
More information about the Digitalmars-d
mailing list