Bug 24531 – foreach lowering fails to compile with dip1000 and std.array.array

Status
NEW
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2024-05-01T21:53:03Z
Last change time
2024-12-13T19:35:01Z
Keywords
industry, rejects-valid, safe
Assigned to
No Owner
Creator
Atila Neves
Moved to GitHub: dmd#20449 →

Comments

Comment #0 by atila.neves — 2024-05-01T21:53:03Z
The code below fails to compile. This is the minimum reduction I could find. The `arrayCtfe` function is the static if branch in std.array.array for __ctfe. This particular example can be fixed with an alternative implementation that calls the range API directly like so: ------ while(!range.empty) { result ~= range.front; range.popFront; } return result; ------ Unfortunately trying to do this in std.array results in compilation failures for other ranges, and checking that this implementation is valid for the range in question with `is(typeof)` or `__traits(compiles)` crashes the compiler. Offending code: ----- struct Target { string[] strings() @safe pure return scope const { return []; } } auto maybeAddDependencies(in Target target, in string projectPath) @safe pure { Target[] targets; scope srcs = targets.filter!(a => true); return srcs .map!(t => t.strings[0]) .arrayCtfe ; } // this is the implementation in std.array.array guarded by `if(__ctfe)` auto arrayCtfe(R)(auto ref R range) { import std.traits: ForeachType; ForeachType!R[] result; // string[] foreach (ref e; range) { result ~= e; } return result; } -----
Comment #1 by bugzilla — 2024-05-10T01:53:11Z
Unfortunately, the example provided is incomplete and not compilable.
Comment #2 by bugzilla — 2024-05-10T02:12:37Z
I need a file, say, test.d, that when compiled with specific switches reproduces the error.
Comment #3 by nick — 2024-05-10T10:56:45Z
It compiles with: import std.algorithm : filter, map; Adding -dip1000 gives: arrayctfe.d(14): Error: scope variable `srcs` assigned to non-scope parameter `range` calling `arrayCtfe` arrayctfe.d(28): which is not `scope` because of `__r115 = range` Replacing the foreach statement with the while code in comment #0 does compile with -dip1000.
Comment #4 by robert.schadek — 2024-12-13T19:35:01Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20449 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB