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.