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

Steven Schveighoffer schveiguy at gmail.com
Tue Jan 21 22:32:45 UTC 2020


On 1/18/20 10:21 AM, FeepingCreature wrote:
> Yes it can!
> 
> D already has support for exactly this kind of thing, with std.traits 
> and `if()` constraints. If you have a metafunction that tries to see if 
> "an alias is usable with string", and it checks that with 
> __traits(canInstantiateCall, foo, string.init) or whatever, then you 
> *should* get a syntax error even in the "return x + 5" case. If you want 
> to avoid that, we don't need language changes, you just need to use the 
> *already existing* mechanism of "if (isNumeric!T)".

Wait, I think I get it.

You want something that says if the constraints allow the instantiation 
to proceed, then instantiate, and display the errors as generated. If 
not, then return false.

So to further explore the stupid example I have:

T foo(T)(T x) if(isNumeric!T)
{
    return X + 5;
}

Then __traits(canInstantiate, foo, "") returns false because the 
constraints are false, and __traits(canInstantiate, foo, 5) produces an 
error because the implementation is bad.

This is definitely possible.

But, it could get really annoying. For instance, you may have to repeat 
the actual implementation in the constraints to get this to match up 
correctly. e.g.:

T foo(T)(T x) if(__traits(compiles, T.init + 5))
{
    return X + 5;
}

I mean, isNumeric might not be what you want exactly, for example, you 
may want foo!BigInt to compile.

But, a constraint-free template might be exactly what you wanted to do. 
Many range types don't care what their element type does, they are just 
focused on being a container for them. So there's no constraints based 
on the type.

The idea has potential.

-Steve


More information about the Digitalmars-d mailing list