Bug 17545 – [REG2.072] __traits(getAttributes, name) evaluates name to value prematurely
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-06-24T16:59:00Z
Last change time
2017-08-07T13:17:19Z
Keywords
industry
Assigned to
nobody
Creator
johanengelen
Comments
Comment #0 by johanengelen — 2017-06-24T16:59:29Z
The following code used to compile with DMD 2.071, but fails for >=2.072.
```
module example;
import std.meta: staticIndexOf;
struct Attrib {}
@Attrib enum TEST = 123;
pragma(msg, __traits(getAttributes,
__traits(getMember, example, "TEST")));
```
Comment #1 by monkeyworks12 — 2017-06-24T17:52:41Z
This code is *supposed* to be equivalent as far as I know, but it actually fixes the issue. Change `@Attrib enum TEST = 123` to `@Attrib enum TEST { val = 123; }` and it will compile (you can also make it immutable; basically anything that introduces an actual symbol).
I think it's because the compiler does not even see the enum; the symbol TEST is replaced with the actual value at the usage site so it's like you're doing `pragma(msg, __traits(getAttributes, 123))`, which of course doesn't make any sense.
Comment #2 by monkeyworks12 — 2017-06-24T17:58:44Z
If you don't want to modify the enum the following code also seems to work. The main thing is to avoid using __traits(getMember) which could get passed a non-symbol.
module example;
import std.meta: staticIndexOf;
import std.traits;
struct Attrib {}
@Attrib enum TEST = 123;
void foo() {
foreach(sym; getSymbolsByUDA!(example, Attrib)) {
pragma(msg, sym.stringof); //Prints 123
}
}
The fact that it prints 123 instead of TEST seems to suggest that it is indeed a problem with the compiler pasting the value where the identifier is used. I'd recommend taking a look at the implementation of getSymbolsByUDA to see how it's done there.
Comment #3 by dlang-bugzilla — 2017-06-24T18:15:19Z