Thread overview
Re: enum type changes according to context ?
Mar 28, 2013
Timothee Cour
Mar 28, 2013
cal
Mar 29, 2013
Jonathan M Davis
March 28, 2013
In code below, does transTable have a well defined type?
it seems to change from line 9 (string[char])
to line 10 (string[dchar])...

rdmd -version=bad main //CT erro
rdmd main //works
----
import std.string;
void main(){
    version(bad){
        auto transTable = ['[' : `\[`];
    }
    else{
        enum transTable = ['[' : `\[`];
    }
    pragma(msg,typeof(transTable)); //string[char] always
    auto s = translate("[", transTable); //CT error with -version=bad only
}
----


Error: translate (string str, string[dchar] transTable, string
toRemove = null) is not callable using argument types
(string,string[char])
March 28, 2013
On Thursday, 28 March 2013 at 23:02:31 UTC, Timothee Cour wrote:
> In code below, does transTable have a well defined type?
> it seems to change from line 9 (string[char])
> to line 10 (string[dchar])...

My guess:
The enum version is like saying this:

auto s = translate("[", ['[' : `\[`]);

here the literal gets implicitly converted to string[dchar]. The auto version is inferred as string[char], so compilation fails.
March 29, 2013
On Thursday, March 28, 2013 16:02:18 Timothee Cour wrote:
> In code below, does transTable have a well defined type?
> it seems to change from line 9 (string[char])
> to line 10 (string[dchar])...
> 
> rdmd -version=bad main //CT erro
> rdmd main //works
> ----
> import std.string;
> void main(){
>     version(bad){
>         auto transTable = ['[' : `\[`];
>     }
>     else{
>         enum transTable = ['[' : `\[`];
>     }
>     pragma(msg,typeof(transTable)); //string[char] always
>     auto s = translate("[", transTable); //CT error with -version=bad only
> }
> ----
> 
> 
> Error: translate (string str, string[dchar] transTable, string
> toRemove = null) is not callable using argument types
> (string,string[char])

The key difference between the two transTables is that the first one creates a variable, whereas the second results in a value that gets copy-pasted wherever it gets used. So, the enum version should be the same as if you used the literal directly.

I believe that the version that the first one fails is because it defaults to char (because '[' will fit in a char) for the key and string for the value (since string literals default to string), and translate doesn't accept string[char].

The reason that the enum succeeds (as would a direct literal) is because the char literal can be inferred to be dchar in order to match the call that it's being passed to (so it's likely being passing a string[dchar]). The inferrence can occur in the enum case, because it's being used directly, whereas in the auto case, the literal's type has to be inferred before the translate call and therefore can't be inferred to match what translate would accept.

- Jonathan M Davis