As described, the DeclDef grammar allows Invariant and UnitTest at module scope. The compiler only permits them within classes, structs, and unions, which seems more correct to me. Given that and bug 2651, I think the grammar should be modified as:
Module:
DeclDefs
DeclDefs:
DeclDef
DeclDef DeclDefs
DeclDef:
AttributeSpecifier
ImportDeclaration
EnumDeclaration
ClassDeclaration
InterfaceDeclaration
AggregateDeclaration
Declaration
UnitTest
StaticConstructor
StaticDestructor
DebugSpecification
VersionSpecification
MixinDeclaration
;
ClassBodyDeclaration:
AggregateDeclDef
Constructor
Destructor
ClassAllocator
ClassDeallocator
StructBodyDeclaration:
AggregateDeclDef
StructAllocator
StructDeallocator
StructConstructor
StructPostblit
StructDestructor
AggregateDeclDef:
DeclDef
Invariant
UnitTest
Comment #1 by ddparnell — 2009-02-08T23:51:05Z
Unit tests are correctly permitted at the module level. A unit test can be used to test free functions as well as class/struct methods.
Comment #2 by jlquinn — 2009-02-09T07:46:23Z
(In reply to comment #1)
> Unit tests are correctly permitted at the module level. A unit test can be used
> to test free functions as well as class/struct methods.
Yes, I see that now. I'm now thinking that to make the distinction in the grammar you need two different versions of AttributeSpecifier - one for module scope that references DeclDef and another for class/struct scope where invariant is allowed.
ClassBodyDeclaration and StructBodyDeclaration still need to reference some kind of DeclDef, though.