| |
![Steven Schveighoffer's Gravatar profile Gravatar of Steven Schveighoffer](//www.gravatar.com/avatar/bdee8ec163786352f9df0d4f421028a1?d=identicon&s=32) | Posted by Steven Schveighoffer in reply to Walter Bright | Permalink Reply |
|
Steven Schveighoffer ![Steven Schveighoffer's Gravatar profile Gravatar of Steven Schveighoffer](//www.gravatar.com/avatar/bdee8ec163786352f9df0d4f421028a1?d=identicon&s=80)
Posted in reply to Walter Bright
| On 11/22/22 1:16 PM, Walter Bright wrote:
> On 11/21/2022 5:41 PM, Timon Gehr wrote:
>> On 22.11.22 01:49, Walter Bright wrote:
>>> On 11/20/2022 1:58 PM, Timon Gehr wrote:
>>>> On 20.11.22 22:32, Walter Bright wrote:
>>>>>
>>>>> But yes, it would be a (small) breaking change.
>>>>
>>>> I really wouldn't want to run into this:
>>>>
>>>> ```d
>>>> enum Role{
>>>> guest,
>>>> member,
>>>> developer,
>>>> }
>>>>
>>>> void main(){
>>>> Role r;
>>>> writeln(r); // error
>> (Should perhaps be auto s = to!string(r);)
>>>> }
>>>> ```
>>>>
>>>> Too messy for me, but up to you.
>>>
>>> I'm not seeing where the shadowing is?
>>
>> That's indeed basically the point. It's invisible.
>
> This code:
>
> ---
> import std.stdio;
>
> enum Role{
> guest,
> member,
> developer,
> }
>
> void main(){
> Role r;
> writeln(r); // error
> }
> ---
>
> compiles successfully and when run prints:
>
> guest
>
To spell it out, when you write `case member:` what does `member` refer to? It currently, in the implementation of Phobos refers to the `member` iteration variable of the foreach inside to!string:
```d
foreach(member; EnumMembers!E) {
```
But if an implicit `with(Role)` is added to the case clause, now it only ever refers to `Role.member`. Essentially, you will end up with a switch that looks like:
```d
switch(e) {
case Role.member: ...
case Role.member: ...
case Role.member: ...
default: ...
}
```
Which will then be a compiler error.
The fix would be to rename the iteration variable to something the user couldn't possibly use. It's not pretty.
-Steve
|