Bug 18194 – hasStaticMember doesn't work with static enum

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-01-05T12:33:18Z
Last change time
2018-01-05T21:08:46Z
Assigned to
No Owner
Creator
FeepingCreature

Comments

Comment #0 by default_357-line — 2018-01-05T12:33:18Z
Steps to reproduce: class X { static int a; static enum b; } static assert(hasStaticMember!(X, "a")); static assert(hasStaticMember!(X, "b")); What should happen: Both asserts should pass. What happens: The second assert fails. The error occurs because enum hasStaticMember(T, string member) = __traits(compiles, &sym);, and enums don't have an address.
Comment #1 by default_357-line — 2018-01-05T12:39:40Z
static assert(hasMember!(X, "b")) does pass, and b shows up in allMembers and derivedMembers.
Comment #2 by issues.dlang — 2018-01-05T13:53:30Z
Except that static on an enum is meaningless and is thus ignored by the compiler. The generated binary is identical whether static is there or not. So, there's really nothing to detect here. It would be just as meaningful if you put pure in front of enum (which for better or worse, does compile).
Comment #3 by default_357-line — 2018-01-05T16:01:53Z
I'd expect static-on-enum to influence whether you could do this.member or Class.member. Is this not the case?
Comment #4 by issues.dlang — 2018-01-05T21:08:46Z
No, because an enum doesn't get associated with an instance. Like an alias, it's just a scoped declaration. e.g. struct S { enum a = "foo"; static enum b = "bar"; } void main() { auto c = S.a; auto d = S.b; auto e = S.init.a; auto f = S.init.b; } compiles just fine. And while it seems a bit bizarre, this compile just fine too struct S { alias a = int; static alias b = int; } void main() { alias c = S.a; alias d = S.b; alias e = S.init.a; alias f = S.init.b; } For that matter, the only influence that static has on variables over whether you can use the type name or can use an an instance is that non-static variables have to be referred to via the instance that they're associated with, whereas static variables can be accessed either via the type name or via an instance. Though in that case, it doesn't have anything do with static being ignored like it does in the examples above. All of this is why it was actually surprisingly difficult to come up with an implementation of hasStaticMember which works in the general case. But hasStaticMember can't distinguish between stuff that the compiler treats as the same.