Bug 9930 – enum members should be hidden in an enum instance
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-04-14T08:28:00Z
Last change time
2016-08-27T23:28:30Z
Keywords
pull
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2013-04-14T08:28:02Z
enum E
{
A,
B
}
void main()
{
E e;
if (e.A) // should have been "if e == E.A"
{
}
}
This compiles, and it was a bug in my code. I don't see the benefit of being able to access enum member through the instance instead of through the type. So I think the above should become an error.
Of course "if (E.A)" through the type is and will be allowed to compile, but the above might just catch a bug or two in user-code (it certainly wasted my time tracking down the bug).
Comment #1 by andrej.mitrovich — 2013-04-16T11:04:12Z
Note that this actually hides instance members:
struct S
{
int a; // hidden by member "a" in enum E
bool opCmp(S s) { return 1; }
}
enum E : S
{
a = S(1),
b = S(2)
}
void main()
{
E evar = E.a;
assert(evar.a == 1); // Error: evar.a is E here
}
I'm changing the report to a bug.
Comment #2 by andrej.mitrovich — 2013-06-03T10:03:19Z
To make sure Issue 10253 is implementable, I'd still like the following to work (which currently does):
-----
enum E
{
A,
B
}
struct S
{
E e;
alias e this;
}
auto x = S.A; // equivalent to S.e.A, or E.A
-----
Comment #3 by yebblies — 2013-11-22T06:35:37Z
(In reply to comment #2)
> To make sure Issue 10253 is implementable, I'd still like the following to work
> (which currently does):
>
> -----
> enum E
> {
> A,
> B
> }
>
> struct S
> {
> E e;
> alias e this;
> }
>
> auto x = S.A; // equivalent to S.e.A, or E.A
> -----
I don't think we can have both.
Comment #4 by andrej.mitrovich — 2013-11-22T06:42:43Z
Going to label this as an enhancement, we'll see later if it's worth implementing.
Comment #5 by yebblies — 2013-11-22T06:56:53Z
(In reply to comment #4)
> Going to label this as an enhancement, we'll see later if it's worth
> implementing.
I don't see any point in being able to access enum members through an enum variable.
https://github.com/D-Programming-Language/dmd/pull/2857
Comment #6 by bugzilla — 2013-11-23T12:40:30Z
I don't agree that this is a bug, as D is just following the scoping rules, and this is a natural consequence. I also am not convinced a special case needs to be added to the scoping rules for this, and worry that it would needlessly break existing code.
Comment #7 by yebblies — 2013-11-23T19:15:07Z
(In reply to comment #6)
> natural
enum I { a, b, d, e, g, k, m, n, o, s, t, u };
void main()
{
auto x = I.t.s.a.b.u.g.a.n.d.m.a.k.e.s.n.o.s.e.n.s.e;
}
Comment #8 by bugzilla — 2013-11-25T12:33:50Z
While it looks odd, it's a natural consequence of the lookup rules, and I don't think that adding special cases helps in the long run.
Comment #9 by yebblies — 2013-11-25T20:29:44Z
(In reply to comment #8)
> While it looks odd, it's a natural consequence of the lookup rules, and I don't
> think that adding special cases helps in the long run.
I disagree, but this can wait.
Comment #10 by issues.dlang — 2013-11-25T20:47:54Z
This is similar to being able to call a static member function via an instance rather than the type, which is also something that I think is horrible and ideally would go. Unfortunately, several other languages permit it, but IMHO, it provides no value, is bug-prone, and it actually prevents us from overloading on static-ness (i.e. A.foo() calls the static foo and a.foo() calls the non-static foo), which is particularly problematic for opCall.
So, this (as well as being able to call static functions via instances) are the sorts of rules that I find very counterintuitive and negative in terms of their effects. I don't know if we can fix them at this stage in the game (particularly with regards to static member functions, since other languages make the same mistake that we do in that regard), but ideally, D would be fixed so that you can't access an enum member via an instance and so that you can't access a static member via an instance. To allow it is just broken and bug-prone IMHO.
Comment #11 by issues.dlang — 2013-11-25T21:01:05Z
And the lookup rules must function very differently from how many programmers would expect them to work if the compiler is finding e.A at all, since there is no A in e, as e is an int, which has only init, min, and max, and there are no UFCS functions named A. It's E that has A in it, not e.
Comment #12 by simen.kjaras — 2013-11-26T00:14:08Z
(In reply to comment #11)
> e is an int
Certainly not! This is like saying struct are just void[].
Comment #13 by issues.dlang — 2013-11-26T01:22:22Z
>> e is an int
> Certainly not! This is like saying struct are just void[].
The base type of E is int. void[] is not the base type of anything. The two are completely different, though it's true that e is not _exactly_ an int.
Regardless, the point is that it's ridiculous to consider enum values to be in the name scope of anything other than the enum that they belong to. Having them be in the name scope of a variable of the enum's type makes no sense.
Comment #14 by bugzilla — 2013-11-27T18:12:35Z
> it actually prevents us from overloading on static-ness
I don't agree with static meaning that something goes into some separate namespace, and I believe it is an advantage to the class designer to be able to refactor things in and out of static without breaking user code.
It is not the instance that determines which names are visible, it is the type.
The scoping rules are straightforward, and I believe that trying to fix them for all sorts of special cases is just going to cause more problems, not the least of which is greatly expanded documentation attempting to explain it.
Comment #15 by andrej.mitrovich — 2016-08-27T23:28:30Z
Yeah I'm afraid I've seen so much code in the wild which depends on this feature, that it would make it very hard to change this without breaking everyone's code. The benefits of the breakage would be too small in this case. I'm closing this.