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.

Reply via email to