Simple and effective approaches to constraint error messages
Meta via Digitalmars-d
digitalmars-d at puremagic.com
Tue Apr 26 08:35:34 PDT 2016
On Monday, 25 April 2016 at 17:52:58 UTC, Andrei Alexandrescu
wrote:
> Idea #2: Allow custom error messages
> ====
>
> The basic idea here is to define pragma(err, "message") as an
> expression that formats "message" as an error and returns
> false. Then we can write:
>
> R find(R, E)(R range, E elem)
> if ((isInputRange!R || pragma(err, R.stringof~" must be an
> input range")
> &&
> (is(typeof(range == elem) == bool) || pragma(err, "..."))
>
> Now, when printing the failed candidate, the compiler adds the
> error message(s) produced by the failing constraint.
>
> The problem with this is verbosity - e.g. we almost always want
> to write the same message when isInputRange fails, so naturally
> we'd like to encapsulate the message within isInputRange. This
> could go as follows. Currently:
>
> template isInputRange(R)
> {
> enum bool isInputRange = is(typeof(
> (inout int = 0)
> {
> R r = R.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
> }));
> }
>
> Envisioned (simplified):
>
> template lval(T)
> {
> static @property ref T lval() { static T r = T.init; return
> r; }
> }
>
> template isInputRange(R)
> {
> enum bool isInputRange =
> (is(typeof({if(lval!R.empty) {}})
> || pragma(err, "cannot test for empty")) &&
> (is(typeof(lval!R.popFront())
> || pragma(err, "cannot invoke popFront")
> (is(typeof({ return lval!R.front; }))
> || pragma(err, can get the front of the range));
> }
>
> Then the way it goes, the compiler collects the concatenation
> of pragma(msg, "xxx") during the invocation of isInputRange!R
> and prints it if it fails as part of a constraint.
>
> Further simplifications should be possible, e.g. make is()
> support an error string etc.
The problem here is that *every* constraint must be modified,
which will a long and tedious process. The nice part about 1 is
that every constraint gets it for free. Applying it recursively
would provide a nice "stack trace" of constraint failure so the
user can see exactly what went wrong and where. The problem then
becomes the verbosity of errors, but we already have ways of
dealing with that such as the -v switch.
More information about the Digitalmars-d
mailing list