Discussion Thread: DIP 1044--Enum Type Inference--Community Review Round 1

Steven Schveighoffer schveiguy at gmail.com
Wed Nov 23 03:24:30 UTC 2022


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


More information about the Digitalmars-d mailing list