The evils of __traits(compiles)

Steven Schveighoffer schveiguy at gmail.com
Thu Jan 21 23:05:16 UTC 2021


On 1/21/21 3:27 PM, H. S. Teoh wrote:
> Ran into this today: was submitting a PR for the ddbus package, which
> has a function .registerMethods that allows automatic registration of
> DBus methods by introspecting a class object, and generating the
> appropriate setHandler calls to the router object.  Since not all method
> signatures can be supported by DBus, .registerMethods uses
> __traits(compiles) as a quick way of determining whether setHandler is
> usable on a particular method (unsupported methods will not compile when
> passed to setHandler, so they will be skipped).
> 
> Unfortunately, my PR touches one of the functions used by setHandler. A
> typo caused a compile error inside setHandler itself, but since
> __traits(compiles) does not distinguish between errors caused by the
> candidate method and errors inside setHandler itself, the erroneous code
> simply caused *all* methods to be skipped -- silently.  The problem
> would not be noticed until runtime when some methods mysteriously go
> missing. :-(
> 
> This problem isn't specific to ddbus; I've run into this in a lot of D
> code that's heavy on compile-time introspection.  __traits(compiles) is
> a quick and easy way of getting code to work, but it inevitably leads to
> pain because of the way it gags *all* compile errors, including the ones
> you didn't expect and probably should be reported.
> 
> tl;dr: __traits(compiles) is evil, and should be avoided. Unless you
> *really* mean, literally, "does this piece of code compile", and you're
> not using that as a stand-in for some other intended semantics (like
> "does X conform to Y's signature constraints" or some such).  SFINAE is
> evil. >:-(

https://forum.dlang.org/post/rj5hok$c6q$1@digitalmars.com

-Steve


More information about the Digitalmars-d mailing list