Difference between "can call" and "can compile"

Steven Schveighoffer schveiguy at gmail.com
Wed Sep 16 19:12:47 UTC 2020


On 9/16/20 12:59 PM, Nick Treleaven wrote:
> On Tuesday, 8 September 2020 at 18:59:00 UTC, Steven Schveighoffer wrote:
>>    void toString(Output)(Output output) if (isOutputRange!(Output, 
>> dchar))
>>    {
>>       put(output, "hello, this is an S!"); // no import of std.range.put
>>    }
> ....
>> if writeln checked using the proposed __traits(instantiates) instead 
>> of __traits(compiles) on the call to S.toString(lockedTextOutput) (or 
>> whatever it does), then instead of the wrong path, I get a compilation 
>> error, telling me that my toString doesn't compile.
> 
> In theory, `is(typeof(S.init.toString(suitableOutputRange)))` could be 
> true even if there is a semantic error in the body of your S.toString 
> method. The typeof expression only needs to resolve the method then 
> produce the type of that method. You specified the return type as `void` 
> (not `auto`), so it is overkill to check the semantics of the method 
> body at this point in compilation (it might not even get called).
> 
> If typeof was changed to do less work, perhaps `is(typeof(...))` could 
> do what you want.

Ehh... I don't care what it returns. I care that it can be called. The 
fact that I wrote void in my toy example is not important.

But you bring up a good point. Something like "see if this lambda 
compiles" might included figuring out the return type of a function. 
Which in turn means to analyze the body (if it's an auto return).

So the formulation of a constraint may have to avoid using "see if this 
lambda works" techniques to avoid having to compile everything.

-Steve


More information about the Digitalmars-d mailing list