https://issues.dlang.org/show_bug.cgi?id=12821
Issue ID: 12821 Summary: Missed redundant storage class / protection errors. Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: DMD Assignee: nob...@puremagic.com Reporter: ibuc...@gdcproject.org There are cases where redundant storage classes are caught, and others where it just slides through undetected. Example: final final void foo() { } // Error, redundant 'final' final shared final void foo() { } // Error, redundant 'final' final static final void foo() { } // OK We can find the exact culprits by iterating through each storage class to find missed cases. static static void foo() { } // OK extern extern void foo() { } // OK align align void foo() { } // OK debug debug void foo() { } // OK And we can test this: shared shared void foo() { } // Error, redundant 'shared' shared static shared void foo() { } // OK shared extern shared void foo() { } // OK shared extern(D) shared void foo() { } // OK shared align shared void foo() { } // OK shared debug shared void foo() { } // OK Other cases include mixing and matching any protection/storage class together. const const void foo() { } // Error, redundant 'const' protected protected void foo() { } // Error, redundant 'protection' const protected const void foo() { } // OK protected const protected void foo() { } // OK Resulting in allowing you to even mix conflicting storage classes together. const immutable void foo() { } // Error, conflicting const package immutable void foo() { } // OK const static immutable void foo() { } // OK Penultimately, the following throw an error unless you specify void. All of which seems redundant as there's no return type. immutable foo() { } // Without 'this' cannot be immutable immutable void foo() { } // OK const foo() { } // Without 'this' cannot be const const void foo() { } // OK inout foo() { } // Without 'this' cannot be inout inout void foo() { } // OK shared foo() { } // Without 'this' cannot be shared shared void foo() { } // OK Lastly, these are considered perfectly valid, if somewhat odd. ref foo() { } // OK, inferred as 'ref void' ref void foo() { } // OK auto void foo() { } // OK auto int foo() { return 0; } // OK, redundant 'auto' auto double foo() { return 0; } // OK, redundant 'auto' All these tests are using functions declared at module scope. --