Difference between "can call" and "can compile"

FeepingCreature feepingcreature at gmail.com
Wed Sep 16 05:45:41 UTC 2020


On Wednesday, 16 September 2020 at 00:28:59 UTC, Steven 
Schveighoffer wrote:
>
> Yes, but input ranges and Phobos are not the only things that 
> depend on UFCS.
>
> There's also a question of whether a free function can be 
> called with a provided type, which has no analogue to 
> __traits(hasMember).
>
>> I do agree with what you are saying, in fact it almost seems 
>> like __traits(compiles) is a code smell. There's usually a 
>> better way to express it, and as is with the case you are 
>> talking about, a different feature would be more appropriate 
>> and provide better error messages.
>
> Yes, exactly. I've spent way more than my fair share unraveling 
> via library surgery what the compiler should be able to do 
> itself, as long as the proper tools existed.
>
> Don't get me wrong, I'd be fine with a solution that doesn't 
> need a new feature (that would be ideal actually).
>
> -Steve

Hm!

I may have something:

```
public template hasInstantiationFor(alias F, T)
{
   import std.traits : ReturnType;
   struct NoMatch { }
   alias proxy = F;
   alias proxy(T) = () => NoMatch();
   enum hasInstantiationFor = !is(ReturnType!(proxy!T) == NoMatch);
}
```

I could swear this used to straight up not work, but it seems to 
work now, at least for small local tests.

I can't put it into production because it runs into a flood of 
unrelated bugs if I try to use it in an actual project. I swear 
it never ends with this language...

But I'll try to dustmite this and maybe in DMD 2.095 we'll have a 
solution that actually works.

Though it only works for templates that are characterized by 
specialization, not template inconditions. As far as I can tell 
there's no way to see if a template matches inconditions, because 
there's no "fallback incondition" like there is with 
specializations.

So canInstantiate is still needed.


More information about the Digitalmars-d mailing list