Feature request: __traits(canInstantiate), like __traits(compiles) but without suppressing syntax errors

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Jan 15 18:13:08 UTC 2020

On Wed, Jan 15, 2020 at 03:13:08PM +0000, FeepingCreature via Digitalmars-d wrote:
> Right now it's impossible to check "is there a valid (template)
> specialization for this function call" without also saying "and by the
> way, if there's a syntax error in the function, suppress the error and
> return false."
> This makes many Phobos and library functions very annoying to use.

Yeah, the error-gagging method of speculative template instantiation has
been costing me lots of wasted time, too, esp. in Phobos range functions
like .find, .filter, etc., because a single typo in the lambda argument
causes the template to fail to instantiate, but the only information you
get out of it is "cannot instantiate because it must satisfy
isInputRange", but the reason it can't satisfy isInputRange is because a
syntax error makes the type void (or _error_), but it doesn't tell you
WHY the type is void or _error_.  Is it a syntax error? A mistyped
symbol? A mismatching type? Who knows, you can't tease that information
out of the compiler because errors are gagged. And no, turning on
verbose output does not help because it floods you with truckloads of
"errors" for *other* template instantiations that are completely
unrelated to this one (and that actually *worked*, so that's just
meaningless noise), and you're left to dig through the mountains of
messages to find out which one might actually be relevant to your

Furthermore, the error often crops up deep inside a long UFCS chain with
multiple levels of nesting, so you can't exactly insert diagnostic
messages in the middle to figure out where the problem is. The whole
chain is one expression, after all, and all you'll get out of the
compiler is that the entire expression failed to compile. But it could
be as simple as a single typo deep inside one of the lambdas, or a
missing import, and you've no idea where.

The only way I could diagnose problems of this sort was to copy-n-paste
the entire chain, comment out most of the except the first N steps, and
then iteratively uncomment them until it stops compiling. Then once it
stops compiling and I identified the offending lambda, copy-n-paste the
lambda body into an actual fake function with actual parameter types
that the compiler is forced to compile on its own -- because otherwise
all errors are gagged and it's impossible to know what the compiler
didn't like about it -- just to get the actual error message out of the

And very often, it's a really trivial problem like a typo, a missing
import, or forgetting to convert a type to the expected return type,
etc.. The sort of error you'd expect the compiler to pinpoint with the
exact line number and reason, and that you can fix in 30 seconds. But
no thanks to gagged errors, it often takes more like 30 *minutes* just
to narrow down the cause of the problem.

All in all, it makes for a very poor user experience. No wonder the
naysayers have no good things to say about Phobos templates!

> A simple (?) fix for this would be adding a new trait that checks if
> the expression resolves to a valid template specialization, without
> attempting to also check if the function body compiles, or else
> without suppressing internal syntax errors.

+1000. This would've saved me HOURS of debugging trivial problems like
missing imports and mistyped identifiers.


Chance favours the prepared mind. -- Louis Pasteur

More information about the Digitalmars-d mailing list