On Friday, 21 November 2014 at 04:08:52 UTC, Steven Schveighoffer
wrote:
OK, so I'm writing some traits that I'd like my objects to
satisfy. And I'm having the worst time debugging them.
Most of the traits in D look like this:
enum isSomeType(T) = __traits(compiles, (T t){
// some statements using t
// some asserts
// some static asserts
});
All good.
Now, let's test my object:
unittest
{
static assert(isSomeType!SomeObject);
}
Nope. Now, how the hell do I figure out why?
I have found the following technique most valuable:
1. Create a function called "testSomeType(T)(T t)", make it's
body the same as the trait
2. Instead of static asserting the trait, call the function
Much better results! Whichever part of the trait doesn't work
shows up as a legitimate error, and I can fix the object or the
trait.
Now, this idiom of using __traits(compiles, ...) is used
everywhere in phobos. Often times you see things like:
void foo(T)(T t) if (hasSomeTrait!T && hasSomeOtherTrait!T &&
alsoHasThisOne!T) { ...
If this doesn't compile, the compiler says "Error template
instance blah blah does not match template declaration blah
blah blah"
Useless...
Now, even if I want to use my cool technique to figure out
where the issue is, I have to do it one at a time to each
trait, and I may have to temporarily comment out some code to
avoid triggering an error before I get to that point.
When I first came to write this post, I wanted to ask if anyone
thought it was a good idea to replace the __traits(compiles,
someLiteral) with __traits(compiles, someFunctionTemplate!T)
somehow, so if one couldn't do it, you had some easy way to
debug by calling someFunctionTemplate.
But I hate that idea. This means you have all these do-nothing
functions whose sole existence is to debug traits. When the
traits themselves can just do it for you.
Can anyone figure out a good solution to this problem? I like
template constraints, but they are just too black-boxy. Would
we have to signify that some enum is actually a trait and so
the compiler would know to spit out the junk of compiling?
Would it make sense to add some __traits function that allows
one to signify that this is a special trait thing?
This is one area that D's templates are very user-unfriendly.
-Steve
There has been a bit of promising work done by Shammah
Chancellor. It's a bit more heavyweight than a template returning
true or false, but it's also more powerful and makes for better
error messages.
http://forum.dlang.org/thread/[email protected]