A proper WAT moment

Paul Backus snarwin at gmail.com
Tue Oct 15 14:32:49 UTC 2019


On Tuesday, 15 October 2019 at 09:34:41 UTC, Simen Kjærås wrote:
> void fun() {
>     pragma(msg, __LINE__, " ", 
> __traits(compiles,__traits(getMember, S, "e")));
> }

__traits(compiles) is lying to you again. If you replace it with

__traits(getMember, S, "e")

...you'll get an error.


> Interestingly, the code does of course actually compile:
>
> struct S3 {
>     void fun() {
>         alias a = __traits(getMember, S, "e");
>     }
> }

I think this is the key. It compiles if you put it on the 
right-hand side of an alias declaration, but *not* if you write 
it as a bare expression:

struct S3 {
     void fun() {
         __traits(getMember, S, "e"); // Error
     }
}

The difference is that in an alias declaration, 
__traits(getMember) isn't evaluated as a function call, whereas 
in a naked expression, it is. So the question becomes, why is 
__traits(getMember) evaluating @property functions differently in 
different contexts?

I suspect the answer has to do with the difference between the 
two error messages. In the context of a free function, it's "need 
`this` for `e`"--i.e., you're calling a member function without a 
receiver--so the compiler can infer that you didn't mean to call 
the function at all. In the context of a member function, 
however, it's "`this` needs to be type `S`, not `S2`"--i.e., 
you're (implicitly) calling a member function on the wrong type 
of receiver--so the compiler treats it the same as any other 
function call with incorrect arguments, and assumes you actually 
meant it.

Of course, this is speculation; it would take looking at the 
compiler source to be sure.


More information about the Digitalmars-d-learn mailing list