Difference between "can call" and "can compile"

Nick Treleaven nick at geany.org
Wed Sep 16 16:59:46 UTC 2020

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.

More information about the Digitalmars-d mailing list