On Thursday, 27 December 2018 at 03:52:52 UTC, Johannes Loher wrote:
Hey all,

I am a bit confused about the inferred types of function literals which do not name their parameters (something like `(int) {}`). The confusion arises from the fact that the inferred type sometimes is `void` (might be the case, because the function literal is inferred to be a template) and sometimes it is something like `void function(bool _param_0) pure nothrow @nogc @safe`. What is really weir is that seems to depend on the type of the parameter. Here is small example showing what happens for different parameter types: https://run.dlang.io/is/xSMZZu

Also note that this only happens for function literals. For regular functions and member functions, `void` is never inferred, but only types like `pure nothrow @nogc @safe void(MyClass _param_0)`.

Has anybody any idea what is going on here? Is this a bug?

As you suspect, some of the function literals are being interpreted as templates--specifically, the ones whose parameters are parsed as "identifiers" rather than built-in types. Keep in mind that from the parser's perspective, `string`, `size_t`, and `Object` aren't any different from other user-defined type names or aliases. That they happen to be defined in the D runtime is irrelevant.

You can see that this is true by running the following example:

    alias f = (string) {  };
    writeln(typeof(f!int).stringof);

Unfortunately, this behavior is mentioned exactly nowhere in the language spec. Both the section on function literals [1] and the grammar for function parameters to which it refers [2] fail to mention any circumstance in which a parameter declaration may consist only of a name, without a type. As with many things in D, one can only figure out what the *actual* rules are through trial and error.

[1] https://dlang.org/spec/expression.html#function_literals
[2] https://dlang.org/spec/function.html#grammar

Reply via email to