Simple and effective approaches to constraint error messages
QAston via Digitalmars-d
digitalmars-d at puremagic.com
Mon Apr 25 14:21:12 PDT 2016
On Monday, 25 April 2016 at 17:52:58 UTC, Andrei Alexandrescu
wrote:
> Idea #1: Detect and use CNF, print which clause failed
> ====
>
> CNF (https://en.wikipedia.org/wiki/Conjunctive_normal_form) is
> a formula shape in Boolean logic that groups clauses into a
> top-level conjunction.
>
> The compiler could detect and use when CNF is used (as in the
> example above), and when printing the error message it only
> shows the first failing conjunction, e.g.:
>
> /d935/f781.d(16): Error: template f781.find cannot deduce
> function from argument types !()(NotARange, int), candidates
> are:
> /d935/f781.d(3): f781.find(R, E)(R range, E elem) constraint
> failed: isInputRange!NotARange
>
> This is quite a bit better - it turns out many constraints in
> Phobos are rather complex, so this would improve many of them.
> One other nice thing is no language change is necessary.
Improvement in the generic case is a must. I personally either
comment out the constraint in the lib source (if I can) or
recreate the predicate in a context where I actually can see the
error message. That's tedious and makes me hate template
constraints because for templated libraries the source is there
anyway, I prefer to be given real error (which shows me the exact
issue) rather than a mystery puzzle.
Could your proposal be extended with showing the evaluation for
isInputRange!NotARange to see why it returns false for given
type, i.e. to see that compiler error:
> Error: no property 'empty' for type 'NotARange'
So for example the error message could look like:
/d935/f781.d(16): Error: template f781.find cannot deduce
function from argument types !()(NotARange, int), candidates
are:
/d935/f781.d(3): f781.find(R, E)(R range, E elem) constraint
failed: isInputRange!NotARange
constraint stacktrace:
std.range.primitives.isInputRange!NotARange
boolean expression: is(typeof(
(inout int = 0)
{
NotARange r = NotARange.init; // can define a range
object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range
}));
failed with error: no property 'empty' for type 'NotARange'
Btw. I see you've taken a focus on making D more usable. Probably
teaching D to new people gave you some very needed perspective
:P. Big thanks!
More information about the Digitalmars-d
mailing list