Thread overview
Inconsistency between `AllMembers` and `hasMember`
Nov 17, 2018
drug
Nov 17, 2018
Adam D. Ruppe
Nov 17, 2018
drug
Nov 17, 2018
Adam D. Ruppe
Nov 18, 2018
drug
Nov 18, 2018
Stanislav Blinov
Nov 18, 2018
bauss
Nov 18, 2018
Stanislav Blinov
Nov 18, 2018
drug
Nov 18, 2018
Stanislav Blinov
November 17, 2018
https://run.dlang.io/is/IygU5D

AllMembers states that struct S contains "this" member, but hasMember negates it. Is it bug or misusing?
November 17, 2018
On Saturday, 17 November 2018 at 20:54:24 UTC, drug wrote:
> https://run.dlang.io/is/IygU5D
>
> AllMembers states that struct S contains "this" member, but hasMember negates it. Is it bug or misusing?

I'm not sure what it is supposed to do, but since this is kinda special - it is a keyword for the constructor - I wouldn't expect it to be accessible this way in any reliable manner...
November 18, 2018
On 18.11.2018 0:09, Adam D. Ruppe wrote:
> On Saturday, 17 November 2018 at 20:54:24 UTC, drug wrote:
>> https://run.dlang.io/is/IygU5D
>>
>> AllMembers states that struct S contains "this" member, but hasMember negates it. Is it bug or misusing?
> 
> I'm not sure what it is supposed to do, but since this is kinda special - it is a keyword for the constructor - I wouldn't expect it to be accessible this way in any reliable manner...
Well, this is another question. I mean that if AllMembers returns something it should exist. If it is special member and can not be accesible AllMembers shouldn't return it.

Another problem I'm trying to resolve is that if I define struct S outside of unittest or inside of unittest but using static qualifier AllMembers does not return "this". Also if struct S do not have methods AllMembers also doesn't return "this". It looks strange for me, but first of all it complicates my code.
November 17, 2018
On Saturday, 17 November 2018 at 21:33:37 UTC, drug wrote:
> Another problem I'm trying to resolve is that if I define struct S outside of unittest or inside of unittest but using static qualifier AllMembers does not return "this". Also if struct S do not have methods AllMembers also doesn't return "this". It looks strange for me, but first of all it complicates my code.

That's because the compiler passes it a hidden pointer to refer to the context outside. The compiler could perhaps be smarter about it, and see if those methods actually refer to the context, but it seems to simply say if the method is there, it might refer to it and it adds the context pointer (note that S.sizeof increases too) and a magic constructor to set it.
November 18, 2018
On 18.11.2018 1:26, Adam D. Ruppe wrote:
> 
> That's because the compiler passes it a hidden pointer to refer to the context outside. The compiler could perhaps be smarter about it, and see if those methods actually refer to the context, but it seems to simply say if the method is there, it might refer to it and it adds the context pointer (note that S.sizeof increases too) and a magic constructor to set it.
Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?
November 18, 2018
On Sunday, 18 November 2018 at 00:51:51 UTC, drug wrote:
> On 18.11.2018 1:26, Adam D. Ruppe wrote:
>> 
>> That's because the compiler passes it a hidden pointer to refer to the context outside. The compiler could perhaps be smarter about it, and see if those methods actually refer to the context, but it seems to simply say if the method is there, it might refer to it and it adds the context pointer (note that S.sizeof increases too) and a magic constructor to set it.
> Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?

It's only "hidden" in that there's no symbol to access it. But you can still access it via .tupleof, and it still of course affects the ABI (i.e. S.sizeof is always at least pointer size when S is nested).
If you want to iterate fields, .tupleof is a better way to do it. As for that hidden pointer, you can just test with __traits(isNested, S) whether that's present, and just don't look at the last field.
November 18, 2018
On Sunday, 18 November 2018 at 02:37:13 UTC, Stanislav Blinov wrote:
> On Sunday, 18 November 2018 at 00:51:51 UTC, drug wrote:
>> On 18.11.2018 1:26, Adam D. Ruppe wrote:
>>> 
>>> That's because the compiler passes it a hidden pointer to refer to the context outside. The compiler could perhaps be smarter about it, and see if those methods actually refer to the context, but it seems to simply say if the method is there, it might refer to it and it adds the context pointer (note that S.sizeof increases too) and a magic constructor to set it.
>> Well, if "this" means hidden pointer then it never should be returned by AllMembers at all, isn't it?
>
> It's only "hidden" in that there's no symbol to access it. But you can still access it via .tupleof, and it still of course affects the ABI (i.e. S.sizeof is always at least pointer size when S is nested).
> If you want to iterate fields, .tupleof is a better way to do it. As for that hidden pointer, you can just test with __traits(isNested, S) whether that's present, and just don't look at the last field.

But in that case shouldn't you be able to tell whether it has it or not through hasMember?
November 18, 2018
On Sunday, 18 November 2018 at 09:10:57 UTC, bauss wrote:
> On Sunday, 18 November 2018 at 02:37:13 UTC, Stanislav Blinov wrote:

>> It's only "hidden" in that there's no symbol to access it...

> But in that case shouldn't you be able to tell whether it has it or not through hasMember?

Yah, a case for inconsistency could be made here. IMHO it should just have some reserved name like __context.
November 18, 2018
On 18.11.2018 5:37, Stanislav Blinov wrote:
> 
> It's only "hidden" in that there's no symbol to access it. But you can still access it via .tupleof, and it still of course affects the ABI (i.e. S.sizeof is always at least pointer size when S is nested).
> If you want to iterate fields, .tupleof is a better way to do it. As for that hidden pointer, you can just test with __traits(isNested, S) whether that's present, and just don't look at the last field.

But what is the reason for someone to use this pointer even via .tupleof? I still think AllMember shouldn't return it at all. Of course I can filter it using isNested or just comparing with "this" leteral during iteration. But it complicates things I believe.

P.S. using isNested seems to be more portable solution than comparing with leteral but is this pointer always the last element in AllMember trait result?
November 18, 2018
Reported:

https://issues.dlang.org/show_bug.cgi?id=19410