Bug 20018 – static foreach with static if and is should permit a declaration

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-07-01T03:23:01Z
Last change time
2024-12-13T19:04:28Z
Assigned to
No Owner
Creator
Adam D. Ruppe
Moved to GitHub: dmd#19597 →

Comments

Comment #0 by destructionator — 2019-07-01T03:23:01Z
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(...))`.
Comment #1 by pro.mathias.lang — 2021-02-10T06:53:55Z
Hit this today with the following code: ```D bool hasLocalAliasing(Types...)() { bool doesIt = false; static foreach (T; Types) { static if (is(T : Channel!CT, CT)) doesIt |= true; } return doesIt; } class Channel (T) {} static assert(!hasLocalAliasing!(Channel!(int), Channel!int)); ``` Agree that this should not happen.
Comment #2 by timon.gehr — 2022-06-28T23:34:34Z
> 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. The underlying issue is that this is not true. --- struct S{} static if(is(S T)){ } static assert(is(S==T)); // passes --- I agree that it would make sense to scope `T` to the body of the `static if`. The implementation would be pretty simple, it could just reuse the mechanism I used to scope the loop variable within the body of `static foreach` (but this is a breaking change).
Comment #3 by robert.schadek — 2024-12-13T19:04:28Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19597 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB