getSymbolsByUDA in constructor/member functions

Arafel er.krali at gmail.com
Thu Jun 16 08:23:20 UTC 2022


On 15/6/22 14:26, cc wrote:
> ```d
> import std.traits;
> class XML {}
> 
> class Def {
>      @XML {
>          int x;
>          int y;
>      }
>      int z;
> 
>      this() {
>          static foreach (sym; getSymbolsByUDA!(Def, XML)) {
>          }
>      }
> }
> 
> void main() {
>      auto def = new Def;
> }
> ```
> ```
> test.d(12): Error: value of `this` is not known at compile time
> test.d(12): Error: value of `this` is not known at compile time
> ```
> 
> Why doesn't this work?  There is nothing in the foreach body.
> 
> ```d
> alias ALL = getSymbolsByUDA!(Def, XML);
> pragma(msg, ALL.stringof);
> ```
> reports `tuple(this.x, this.y)`.  Why is `this.` added?


I think it's a bug either in the `getSymbolsByUDA` implementation, or 
actually rather in the `__traits` system.

A workaround bypassing `getSymbolsByUDA`:

```d
import std.traits;
import std.meta: Alias;

class XML {}

class Def {
     @XML {
         int x;
     	int y;
     }
     int z;

     this() {
         static foreach (sym; __traits(allMembers, Def)) {{
             alias member = Alias!(__traits(getMember, Def, sym));
             static if (hasUDA!(member, XML)) {
                 pragma(msg, member.stringof);
                 pragma(msg, sym);
             }
         }}
     }
}

void main() {
     auto def = new Def;
}
```

As you can see, it's `getMember` who is returning a reference to the 
`this` instance. In my view, this is a bug according the documentation 
and examples [1]. It might be that classes behave differently, but then 
it should be documented.

In fact, it shouldn't work at all and you'd need to instantiate Def: 
`getMember` should fail because `x` and `y` are not static.

Interestingly, `hasUDA` (or rather `__traits(getAttributes, ...)`) later 
doesn't care about the dangling `this` reference, so I'm not sure who is 
to blame here... in any case, at the very least the documentation 
doesn't match the actual behavior.

[1]: https://dlang.org/spec/traits.html#getMember


More information about the Digitalmars-d-learn mailing list