www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to do reflection on alias symbols

reply Arafel <er.krali gmail.com> writes:
Hi all,

Please consider the following currently non-working code:

```d
struct bar {
     public alias pubInt = int;
     private alias privInt = int;
}

static foreach(member ; __traits(allMembers, bar)) {
     // Error: argument `int` has no visibility
     pragma(msg, __traits(getVisibility, __traits(getMember, bar, member)));
}
```

Is there any way to get the visibility, or more generically to reflect 
on an alias member as itself and not as the symbol pointed to without 
resorting to nasty __trait(compiles,...) tricks that fail more often 
than not?
Nov 16 2023
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 16, 2023 3:03:25 AM MST Arafel via Digitalmars-d-learn 
wrote:
 Hi all,

 Please consider the following currently non-working code:

 ```d
 struct bar {
      public alias pubInt = int;
      private alias privInt = int;
 }

 static foreach(member ; __traits(allMembers, bar)) {
      // Error: argument `int` has no visibility
      pragma(msg, __traits(getVisibility, __traits(getMember, bar, member)));
 }
 ```

 Is there any way to get the visibility, or more generically to reflect
 on an alias member as itself and not as the symbol pointed to without
 resorting to nasty __trait(compiles,...) tricks that fail more often
 than not?
Someone may be able to give you some advice on how to better deal with this problem, but in general, aliases don't really exist as far as the compiler is concerned. They get translated to the original type and handled that way rather than treated as a separate type that translates to another type. They exist enough that you can do stuff like give them different visibility attributes for the original symbol, but that pretty much just affects whether you can use the alias, and then it gets replaced with the real thing immediately. As it is, IIRC, it was previously the case that there were bugs where visibility attributes did not affect aliases properly, so it's not at all surprising if there isn't a good way to access the visibility attribute of the alias itself. I would suggest that you open up a bug report for it - https://issues.dlang.org - and certainly, there's a good argument that what you're seeing here is a bug. I fully expect that what you're trying do just wasn't properly considered previously and thus was not dealt with properly when the other bugs for visibility attributes on aliases were fixed however many years ago that was now. I very much doubt that what you're seeing is the intended behavior - or at least I fully expect that if Walter or one of the other compiler devs sees the issue, they will agree that what you're trying to do should work. - Jonathan M Davis
Nov 16 2023
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Thursday, November 16, 2023 6:04:43 PM MST Jonathan M Davis via 
Digitalmars-d-learn wrote:
 I would suggest that you open up a bug report for it -
 https://issues.dlang.org - and certainly, there's a good argument that what
 you're seeing here is a bug. I fully expect that what you're trying do just
 wasn't properly considered previously and thus was not dealt with properly
 when the other bugs for visibility attributes on aliases were fixed however
 many years ago that was now. I very much doubt that what you're seeing is
 the intended behavior - or at least I fully expect that if Walter or one of
 the other compiler devs sees the issue, they will agree that what you're
 trying to do should work.
Actually, it looks like there's already an old bug report on the issue: https://issues.dlang.org/show_bug.cgi?id=12363 So, it has been reported, but it looks it's one of those that's gone under the radar. - Jonathan M Davis
Nov 16 2023
parent reply Arafel <er.krali gmail.com> writes:
On 17/11/23 2:48, Jonathan M Davis wrote:
 On Thursday, November 16, 2023 6:04:43 PM MST Jonathan M Davis via
 Digitalmars-d-learn wrote:
 
 Actually, it looks like there's already an old bug report on the issue:
 
 https://issues.dlang.org/show_bug.cgi?id=12363
 
 So, it has been reported, but it looks it's one of those that's gone under
 the radar.
 
 - Jonathan M Davis
 
Thanks for finding it! I think that in general D could do with a more systematic approach to reflection. For me, it's one of its greatest features, and it's a bit of a pity that it needs to be done in such an ad-hoc manner with all kind of corner cases. I mean, in order to know if something is an `enum`, I need to do: ```d enum isEnum(alias a) = is(typeof(a)) && !is(typeof(&a)); ``` which feels like the wrong approach, and too much error-prone. I also fear I'm forgetting to consider some corner case. There is `is(E == enum)`, but it only works on types, and fails for anonymous enums, because `typeof` returns the base type. I know that `std.traits` was precisely supposed to hide these dirty details, but as of now it also seems to be missing this kind of systematic approach: I'd like things like `isEnum!symbol`, and also `isAlias!symbol`, etc. But I think I digress a bit too much, this would be a topic rather for the general forum. Thanks again for your help!
Nov 17 2023
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, November 17, 2023 2:11:30 AM MST Arafel via Digitalmars-d-learn 
wrote:
 I mean, in order to know if something is an `enum`, I need to do:

 ```d
 enum isEnum(alias a) = is(typeof(a)) && !is(typeof(&a));
 ```

 which feels like the wrong approach, and too much error-prone. I also
 fear I'm forgetting to consider some corner case.

 There is `is(E == enum)`, but it only works on types, and fails for
 anonymous enums, because `typeof` returns the base type.
Well, anonymous enums are what are called manifest constants, so they literally aren't enums as far as their type goes, and the type system does not consider them to be enums. They're just a way to declare constants (they're essentialy the D equivalent of using #define for constants in C/C++). Arguably, they should use a keyword other than enum (and that's been debated in the past), but it's unlikely to change at this point. So, if we were to add something to std.traits for them, it would probably be something more like isManifestConstant than isEnum. In spite of the keyword being used, they really aren't intended to be considered enums. - Jonathan M Davis
Nov 17 2023