Comment #1 by john.loughran.colvin — 2019-10-24T17:40:25Z
This is a regression introduced in 2.065, before which .length and .ptr were found. AFAICT .capacity never worked
Comment #2 by razvan.nitu1305 — 2019-10-30T09:30:19Z
The problem here is that (int[]).length is not a valid D construction:
static assert(__traits(compiles, (int[]).length));
will fail, therefore traits(hasMember) returns false.
length, ptr and capacity were thought to work solely on expressions, not on types (it doesn't make sense to get the pointer of a type) so I'm a bit confused of what the compiler should do here.
sizeof and alignof work because there are type properties.
Comment #3 by razvan.nitu1305 — 2019-10-30T09:31:49Z
Note that if a variable is declared:
int[] a;
traits(hasMember) on a works properly.
Comment #4 by razvan.nitu1305 — 2019-10-30T09:54:20Z
As for capacity, it is not listed on the list of properties for arrays and it is implemented as a druntime function. I guess this bug report opens the philosophical question of what hasMember actually means. For example, sizeof is not actually a member of any type, it is a property that may be queried; that property may be implemented as a function directly in the compiler or it may be a function in druntime or it may be an actual member of the int class; this all depends on how it was actually implemented, which is not something that the user cares.
In my opinion, hasMember should only work on aggregates, because there we are talking about actual scope declarations that have members. builtin types should all return false on hasMember queries because builtin types don't have any members, rather they have properties. If you want to see what properties a type has you can simply use traits(compiles).
Comment #5 by bugzilla — 2019-12-12T10:17:15Z
I agree that hasMember should only work on aggregates. UFCS functions that syntactically look like members are still not members.
Comment #6 by bugzilla — 2019-12-12T10:20:40Z
> traits(hasMember) on a works properly.
Meaning:
int[] array;
pragma(msg, __traits(hasMember, array, "length")); // true
pragma(msg, __traits(hasMember, array, "ptr")); // true
pragma(msg, __traits(hasMember, array, "capacity")); // true
pragma(msg, __traits(hasMember, array, "sizeof")); // true
pragma(msg, __traits(hasMember, array, "alignof")); // true
Gaahhh. It's probably far too late to change this behavior now.
Marking as WONTFIX.