This is valid because enum members are of their parent type.
So whilst, strange to look at, at least it is logical.
---
enum Theme { na, batman }
auto song = Theme.na.na.na.na.na.na.na.na.na.na.na.na.na.na.na.batman;
---
A slight variant on the theme is also valid, because when an ident isn't found, the dotExp is passed on to the base type.
---
struct Batman { int batman; }
enum Theme { na = Batman(0) }
auto song = Theme.na.na.na.na.na.na.na.na.na.na.na.na.na.na.na.batman;
---
Where an issue with this happens though, is when an enum member shares the same name as a base type member or property.
---
struct S { int hide; }
enum E : S { hide = S(42) }
pragma(msg, E); // E
pragma(msg, E.hide); // S(42)
pragma(msg, E.hide); // S(42)
pragma(msg, E.hide.hide); // S(42)
pragma(msg, E.hide.hide.hide); // S(42)
pragma(msg, E.hide.hide.hide.hide); // S(42)
pragma(msg, (cast(S)E.hide).hide); // 42
---
Adding an issue for posterity. Though this seems like an amusing quirk to the language, rather than a problem that requires fixing.
Comment #1 by dfj1esp02 — 2021-06-10T18:08:12Z
Reproduction with classes:
---
class A
{
int a;
}
class B:A
{
enum a=1;
}
int f()
{
B b=new B();
return b.a;
}
static assert(f==1);
---
Comment #2 by robert.schadek — 2024-12-13T19:16:56Z