From the grammar documentation:
Decl:
StorageClasses(opt) BasicType Declarator FunctionBody
DMD rejects the following code:
void function() foo {};
and accepts the following:
void function() foo = {};
According to the grammar spec, the latter should be parsed as a variable declaration whose type is "void function()", with a name of "foo" and an empty struct initializer. (By the way, the grammar does not allow empty struct initializers). This should not pass semantic analysis because a struct literal is not of type void function().
Comment #1 by k.hara.pg — 2014-04-15T10:37:06Z
(In reply to brian-schott from comment #0)
> void function() foo = {};
>
> According to the grammar spec, the latter should be parsed as a variable
> declaration whose type is "void function()", with a name of "foo" and an
> empty struct initializer. (By the way, the grammar does not allow empty
> struct initializers). This should not pass semantic analysis because a
> struct literal is not of type void function().
StructInitializer is defined as follows:
StructInitializer:
{ StructMemberInitializers_opt }
Between braces StructMemberInitializers is optional, so {} is properly accepted.
And, If a delegate variable is initialized by empty StructInitializer, it is treated as a function literal in semantic phase.
https://github.com/D-Programming-Language/dmd/blob/d4f778f96a85de9605a035864d3480e40097df28/src/init.c#L287
Comment #2 by briancschott — 2014-04-15T16:54:11Z
The compiler still rejects this:
void function() bar { writeln("test"); }
The grammar specification says this is valid. It does not require the '=' token. If the compiler's behavior is correct, the specification needs to be changed.
Please do not close bugs while the specification is not consistent with the compiler just because the compiler's behavior is correct.
Comment #3 by briancschott — 2014-04-15T17:27:01Z
The grammar also states that function literals can have contracts by using the FunctionBody rule, but the compiler rejects this:
void function() f = in { assert(true); } body { writeln("hello world"); }
Comment #4 by k.hara.pg — 2014-04-15T23:52:38Z
(In reply to brian-schott from comment #2)
> The compiler still rejects this:
>
> void function() bar { writeln("test"); }
>
> The grammar specification says this is valid. It does not require the '='
> token. If the compiler's behavior is correct, the specification needs to be
> changed.
Even if grammar accept the token list, it could be rejected in some reason.
In this case, it cannot be treated as a function definition, because of the lack of parameter list.
More simple case is:
auto auto x = 1;
This is allowed in grammar, but will be rejected with the error "redundant storage class 'auto'".