I'm trying to figure out how to test whether a UDA struct was initialized with arguments (and change the behavior of the surrounding code if it was. While I was tinkering around with test files, I came up with this little gem:

import std.traits;

struct Attr
{
    string str;
}

@Attr("test")
void foo(){}

@Attr
void bar(){}

void main()
{
    alias UDA = getUDAs!(bar, Attr)[0];
    static if (__traits(hasMember, UDA, "str"))
    {
static if (__traits(compiles, __traits(getMember, UDA, "str")))
        {
__traits(getMember, UDA, "str"); // Compile error! need 'this' for 'str' of type 'string'
        }
    }
}

I can rationalize what the error means -- the compiler wasn't given a string so it requires a concrete object to get the member from. What I don't understand is why *both* of those static ifs passed. If it has the member and I can't get it, and if getting the member compiles yet at the same time it doesn't, I'm not sure how I can actually make this test work.

It would make sense if the attribute over bar wasn't semantically valid, but I can use it in every other way *except* getting the string field out of it.

Am I missing something obvious here?

Reply via email to