the traits trap

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Nov 20 20:08:52 PST 2014


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


More information about the Digitalmars-d mailing list