July 01, 2019
https://issues.dlang.org/show_bug.cgi?id=20018

          Issue ID: 20018
           Summary: static foreach with static if and is should permit a
                    declaration
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: destructionator@gmail.com

Consider the following:

interface Foo(Data) {
    static foreach(memberName; __traits(allMembers, Data))
    static if(is(typeof(__traits(getMember, Data, memberName)) T))
         // use T here
}


That will currently fail, complaining that T is already declared in the scope. And normally, this is true - neither static foreach nor static if introduce a scope.

But static if(is( ... identifier)) is a kinda special case. That does introduce a new symbol... and it is scoped to the body of the static if. So I think static foreach should permit this code as well - the T there does not actually continue to be valid in the next loop iteration (or even below the static if), so the error could, in principle, be removed without breaking anything.

Why is this useful? Well, mostly it is just a convenience: we can then use `T` in place of the longer `typeof(__traits(getMember, Data, memberName))` inside the condition. But that would be really quite nice.

Why not use the {{ code }} trick? Well, two reasons: 1) this is at declaration scope, and the scope block statement is not valid according to the grammar, and 2) I *want* to declare a new member of the interface, and forcing that to be inside a new scope defeats that purpose.

I consider the current error to almost bug - rejects otherwise valid code - but I am still calling this an enhancement since I think it would actually be a special case in the code... just a special case to recognize the already existing special case of `static if(is(...))`.

--