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

IchorDev zxinsworld at gmail.com
Tue Nov 22 06:20:04 UTC 2022


On Monday, 21 November 2022 at 17:50:24 UTC, Walter Bright wrote:
>
> enum A { a }
> enum B { a }
>
> void foo(A);
> void foo(B);
>
> auto bar(T)(T x) { return ....; } // is bar returning an A or a 
> B?
>
> foo(bar!($a));

First thing: I'm going to assume you made a small mistake and 
actually meant `foo(bar($a));` instead of `foo(bar!($a));`. The 
latter would not compile anyway, since you would be trying to 
bind an enum member to a type.

With that assumption in mind, your example would not compile once 
ETI is implemented, because according to the DIP:
> ### 3. Argument lists
> ETI is allowed in the argument lists of function calls and 
> template instantiations _when they can bind to **explicitly 
> typed**_ enum parameters.
```d
enum A{ a,b,c,d }
//[...]
void myTempFn(T)(T param){}

void main(){
//[...]
     myTempFn!A($a);
     myTempFn($a); // error, can't infer a type to instantiate the 
template with from "$a"
}
```

Why is this? Well, `bar(T)(T x)` has no explicitly typed enum 
parameters! When you try to use ETI via `bar($a)` there will be 
no way for the compiler to infer the type of `a`, and you will 
get an ambiguity error.
You might argue that your example shows you instantiating the 
`bar` template inside a call to `foo` which has 2 overloads that 
take an enum parameter. I want to clarify that—just like with 
nested arrays—this is completely meaningless to the evaluation of 
ETI. I will add examples covering this case in the next revision 
of the DIP so that there isn't any doubt it.


More information about the Digitalmars-d mailing list