Help from the compiler when debugging failing template constraints - a pull request
Atila Neves via Digitalmars-d
digitalmars-d at puremagic.com
Mon Sep 28 13:25:20 PDT 2015
I've mentioned this many times before: template constraints are
like unittest blocks with asserts in D: great that they're
built-in easy to use. But when they fail, there's no help in
figuring out why.
I've had many a debugging session (with pragma(msg) of course,
since my bugs were of the compile-time variety and there's no
debugger for that) due to failing to satisfy a template
constraint that I thought I'd implemented the correct functions
for. It'd be nice if the compiler told me why. I did a PR a while
back with an idea from Adam's book but it didn't work in the
context of Phobos and interfaces. I've come up with a PR
(https://github.com/D-Programming-Language/phobos/pull/3677) that
will let users type this:
@models!(MyStruct, isInputRange)
struct MyStruct { ... }
Or this:
struct MyStruct {
...
static assert(models!(MyStruct, isInputRange));
}
When the template constraint isn't satisfied, the compiler will
dutifully tell you why. The only requirement is that there be a
checkXXX function for an isXXX template constraint. I've updated
the original PR for `isInputRange` to make the above code
possible. I chose the name `models` because I just got back from
CppCon and concepts might have tainted my brain. It's unfortunate
to have to specify the type in the UDA version, but it's what the
language as it is now will allow me to do.
I created an input range, verified it compiled, then added a 't'
to the end of `front`. With `models` I got this for both UDA and
static assert versions:
/home/atila/coding/d/dlang/phobos/std/range/primitives.d(182):
Error: template std.range.primitives.front cannot deduce function
from argument types !()(Foo), candidates are:
/home/atila/coding/d/dlang/phobos/std/range/primitives.d(2219):
std.range.primitives.front(T)(T[] a) if
(!isNarrowString!(T[]) && !is(T[] == void[]))
/home/atila/coding/d/dlang/phobos/std/range/primitives.d(2247):
std.range.primitives.front(T)(T[] a) if
(isNarrowString!(T[]))
/home/atila/coding/d/dlang/phobos/std/traits.d-mixin-6771(6771):
Error: template instance
std.range.primitives.checkInputRange!(Foo) error instantiating
concepts.d(81): instantiated from here: models!(Foo,
isInputRange)
Failed: ["dmd", "-unittest", "-main", "-v", "-o-", "concepts.d",
"-I."]
With `static assert(isInputRange!Foo)`, I get this:
concepts.d(87): Error: static assert (isInputRange!(Foo)) is
false
Failed: ["dmd", "-unittest", "-main", "-v", "-o-", "concepts.d",
"-I."]
I prefer the first one. How about you?
Atila
More information about the Digitalmars-d
mailing list