better error messages on isInputRange, etc.
Adam D. Ruppe
destructionator at gmail.com
Wed Feb 26 20:12:02 PST 2014
When isInputRange fails, it doesn't tell us why. Did you not add
empty? Or misspell popFront? It just tells you it isn't a range.
I'm thinking a better way might be to write the check like this:
// compile a regular function so we get full error from the
compiler...
bool checkInputRange(T)() {
if(!__ctfe) { // don't want to *actually* run it
T t = void;
if(t.empty) {}
t.popFront();
auto f = t.front;
}
return true;
}
// and isInputRange is basically the same as today, but the
// helper function isn't anonymous
template isInputRange(T) {
enum isInputRange = is(typeof(checkInputRange!T));
}
Consider this:
struct Test {
int[] s;
bool eampty() { return s.length == 0; }
int front() { return s[0]; }
void popFront() { s = s[1 .. $]; }
}
static assert(isInputRange!Test);
cte.d(33): Error: static assert (isInputRange!(Test)) is false
We know it failed, but we don't know why. Change the assert to
this:
static assert(checkInputRange!Test);
And we get a more helpful error:
cte.d(4): Error: no property 'empty' for type 'Test', did you
mean 'eampty'?
Still not perfect, it points to the helper function line, but at
least the "no property 'empty' for type 'Test'" is a lot more
specific.
Fix the typo and it all works.
Any better ideas? I just sometimes get frustrated, especially
with more complex ranges, when the duck type doesn't work and it
is hard to find why. This is one idea.
On a similar vein, template constraints can lead to some ugly
messages. Why didn't it match any of them? But I think this has
to be a compiler change and might spam all kinds of nonsense,
whereas tweaking isInputRange etc. is a fairly conservative
change that I think will help a lot too.
More information about the Digitalmars-d
mailing list