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