Thread overview
Is this a bug with __traits(derivedMembers)?
Jun 12, 2018
bauss
Jun 12, 2018
bauss
Jun 12, 2018
ag0aep6g
Jun 12, 2018
Bauss
Jun 12, 2018
Basile B.
Jun 12, 2018
bauss
June 12, 2018
See the following: https://run.dlang.io/is/uQ21PH

(I have tried with allMembers too.)

It's like it won't pick up the member that is added using a mixin at line 22.

```
mixin("ubyte[" ~ to!string(__PADDING_SIZE__) ~ "] __PADDING__" ~ member  ~ ";");
```

As you can see if you take sizeof from the struct then it gets the correct size, so it's like the member exists, but you cannot retrieve it with traits.

It's possible to retrieve it manually, so yeah...

If it's a bug then I will file an issue unless someone else will do so.

If it's not a bug, then what's going on and what would the correct solution be?
June 12, 2018
On Tuesday, 12 June 2018 at 13:40:45 UTC, bauss wrote:
> See the following: https://run.dlang.io/is/uQ21PH

Note: Look at the comments in the code.
June 12, 2018
On Tuesday, 12 June 2018 at 13:40:45 UTC, bauss wrote:
> See the following: https://run.dlang.io/is/uQ21PH
>
> (I have tried with allMembers too.)
>
> It's like it won't pick up the member that is added using a mixin at line 22.
>
> ```
> mixin("ubyte[" ~ to!string(__PADDING_SIZE__) ~ "] __PADDING__" ~ member  ~ ";");
> ```

It's because the identifier starts with two underscores. Such identifiers are reserved for internal use, and apparently they're ignored by some (all?) __traits.

I'm not sure if this can count as a bug, but it doesn't look just fine either.

Smaller test case:

----
struct S
{
    int foo, __bar, baz;
}
pragma(msg, __traits(allMembers, S)); /* tuple("foo", "baz") */
----
June 12, 2018
On Tuesday, 12 June 2018 at 14:37:19 UTC, ag0aep6g wrote:
> On Tuesday, 12 June 2018 at 13:40:45 UTC, bauss wrote:
>> See the following: https://run.dlang.io/is/uQ21PH
>>
>> (I have tried with allMembers too.)
>>
>> It's like it won't pick up the member that is added using a mixin at line 22.
>>
>> ```
>> mixin("ubyte[" ~ to!string(__PADDING_SIZE__) ~ "] __PADDING__" ~ member  ~ ";");
>> ```
>
> It's because the identifier starts with two underscores. Such identifiers are reserved for internal use, and apparently they're ignored by some (all?) __traits.
>
> I'm not sure if this can count as a bug, but it doesn't look just fine either.
>
> Smaller test case:
>
> ----
> struct S
> {
>     int foo, __bar, baz;
> }
> pragma(msg, __traits(allMembers, S)); /* tuple("foo", "baz") */
> ----
Thank you. I was not aware of such a gotcha.

Should definitely be documented or yield an error/warning if attempted in user code else you end up with hidden "bugs" like this

June 12, 2018
On Tuesday, 12 June 2018 at 15:42:50 UTC, Bauss wrote:
> On Tuesday, 12 June 2018 at 14:37:19 UTC, ag0aep6g wrote:
>> On Tuesday, 12 June 2018 at 13:40:45 UTC, bauss wrote:
>>> See the following: https://run.dlang.io/is/uQ21PH
>>>
>>> (I have tried with allMembers too.)
>>>
>>> It's like it won't pick up the member that is added using a mixin at line 22.
>>>
>>> ```
>>> mixin("ubyte[" ~ to!string(__PADDING_SIZE__) ~ "] __PADDING__" ~ member  ~ ";");
>>> ```
>>
>> It's because the identifier starts with two underscores. Such identifiers are reserved for internal use, and apparently they're ignored by some (all?) __traits.
>>
>> I'm not sure if this can count as a bug, but it doesn't look just fine either.
>>
>> Smaller test case:
>>
>> ----
>> struct S
>> {
>>     int foo, __bar, baz;
>> }
>> pragma(msg, __traits(allMembers, S)); /* tuple("foo", "baz") */
>> ----
> Thank you. I was not aware of such a gotcha.
>
> Should definitely be documented or yield an error/warning if attempted in user code else you end up with hidden "bugs" like this

Identifier starting with 2 underscores are documented as reserved [1]. I think that we can take this as a clear warning (reached this too once with an enum member that i tried to convert to string...)

[1]: https://dlang.org/spec/lex.html#identifiers

I don't know if more doc is necessary. The warning is at its right place IMO.
June 12, 2018
On Tuesday, 12 June 2018 at 17:24:31 UTC, Basile B. wrote:
> On Tuesday, 12 June 2018 at 15:42:50 UTC, Bauss wrote:
>> On Tuesday, 12 June 2018 at 14:37:19 UTC, ag0aep6g wrote:
>>> On Tuesday, 12 June 2018 at 13:40:45 UTC, bauss wrote:
>>>> See the following: https://run.dlang.io/is/uQ21PH
>>>>
>>>> (I have tried with allMembers too.)
>>>>
>>>> It's like it won't pick up the member that is added using a mixin at line 22.
>>>>
>>>> ```
>>>> mixin("ubyte[" ~ to!string(__PADDING_SIZE__) ~ "] __PADDING__" ~ member  ~ ";");
>>>> ```
>>>
>>> It's because the identifier starts with two underscores. Such identifiers are reserved for internal use, and apparently they're ignored by some (all?) __traits.
>>>
>>> I'm not sure if this can count as a bug, but it doesn't look just fine either.
>>>
>>> Smaller test case:
>>>
>>> ----
>>> struct S
>>> {
>>>     int foo, __bar, baz;
>>> }
>>> pragma(msg, __traits(allMembers, S)); /* tuple("foo", "baz") */
>>> ----
>> Thank you. I was not aware of such a gotcha.
>>
>> Should definitely be documented or yield an error/warning if attempted in user code else you end up with hidden "bugs" like this
>
> Identifier starting with 2 underscores are documented as reserved [1]. I think that we can take this as a clear warning (reached this too once with an enum member that i tried to convert to string...)
>
> [1]: https://dlang.org/spec/lex.html#identifiers
>
> I don't know if more doc is necessary. The warning is at its right place IMO.

If they're reserved the compiler should honestly throw a warning at the very least.

People should have to read through the docs for warnings.
June 12, 2018
On 6/12/18 4:19 PM, bauss wrote:
> On Tuesday, 12 June 2018 at 17:24:31 UTC, Basile B. wrote:
>> I don't know if more doc is necessary. The warning is at its right place IMO.
> 
> If they're reserved the compiler should honestly throw a warning at the very least.
> 
> People should have to read through the docs for warnings.

They are reserved by the language, not necessarily by the compiler. In other words, druntime could potentially define double-underscore items without violating the spec. Having to require a compiler change for such things may be too much.

I didn't know that __traits would ignore them, though, that's pretty interesting.

-Steve